diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27af1e4a..ea923291 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,6 +69,9 @@ jobs: - name: Build run: bin/rails g ruby_ui:component:all --force true + - name: Remove generated docs stubs (conflict with app overrides) + run: git checkout -- app/components/ruby_ui/docs/ 2>/dev/null || rm -rf app/components/ruby_ui/docs/ + - uses: CatChen/check-git-status-action@v2 with: fail-if-not-clean: true diff --git a/app/components/ruby_ui/combobox/combobox_toggle_all_checkbox.rb b/app/components/ruby_ui/combobox/combobox_toggle_all_checkbox.rb index 01a6e811..8cb97c0d 100644 --- a/app/components/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +++ b/app/components/ruby_ui/combobox/combobox_toggle_all_checkbox.rb @@ -12,9 +12,10 @@ def default_attrs { class: [ "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background accent-primary", - "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:opacity-50", - "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none" + "checked:bg-primary checked:text-primary-foreground", + "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none", + "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" ], data: { ruby_ui__combobox_target: "toggleAll", diff --git a/app/components/ruby_ui/form/form_field.rb b/app/components/ruby_ui/form/form_field.rb index dc4b511c..3665f02b 100644 --- a/app/components/ruby_ui/form/form_field.rb +++ b/app/components/ruby_ui/form/form_field.rb @@ -13,7 +13,7 @@ def default_attrs data: { controller: "ruby-ui--form-field" }, - class: "space-y-2" + class: "flex flex-col gap-2" } end end diff --git a/app/components/ruby_ui/form/form_field_error.rb b/app/components/ruby_ui/form/form_field_error.rb index 58c43d35..c47d779c 100644 --- a/app/components/ruby_ui/form/form_field_error.rb +++ b/app/components/ruby_ui/form/form_field_error.rb @@ -13,7 +13,7 @@ def default_attrs data: { ruby_ui__form_field_target: "error" }, - class: "text-xs font-medium text-destructive" + class: "empty:hidden text-sm font-medium text-destructive" } end end diff --git a/app/components/ruby_ui/form/form_field_hint.rb b/app/components/ruby_ui/form/form_field_hint.rb index 5304a259..ba7a5b6c 100644 --- a/app/components/ruby_ui/form/form_field_hint.rb +++ b/app/components/ruby_ui/form/form_field_hint.rb @@ -9,7 +9,7 @@ def view_template(&) private def default_attrs - {class: "text-sm text-muted-foreground"} + {class: "empty:hidden text-sm text-muted-foreground"} end end end diff --git a/app/components/ruby_ui/form/form_field_label.rb b/app/components/ruby_ui/form/form_field_label.rb index 5a7b85b1..bfda2b27 100644 --- a/app/components/ruby_ui/form/form_field_label.rb +++ b/app/components/ruby_ui/form/form_field_label.rb @@ -11,7 +11,7 @@ def view_template(&) def default_attrs { class: [ - "text-sm font-medium leading-none inline-block", + "empty:hidden text-sm font-medium leading-none", "peer-disabled:cursor-not-allowed peer-disabled:opacity-70", "peer-aria-disabled:cursor-not-allowed peer-aria-disabled:opacity-70 peer-aria-disabled:pointer-events-none" ] diff --git a/app/components/ruby_ui/input/input.rb b/app/components/ruby_ui/input/input.rb index fdb3a484..45c79860 100644 --- a/app/components/ruby_ui/input/input.rb +++ b/app/components/ruby_ui/input/input.rb @@ -24,8 +24,9 @@ def default_attrs "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50", "file:border-0 file:bg-transparent file:text-sm file:font-medium", + "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none", "focus-visible:outline-none focus-visible:ring-ring/50 focus-visible:ring-2 focus-visible:border-ring focus-visible:shadow-sm", - "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none" + (@type.to_s == "file") ? "pt-[7px]" : "" ] } end diff --git a/app/components/ruby_ui/native_select/native_select.rb b/app/components/ruby_ui/native_select/native_select.rb new file mode 100644 index 00000000..9c100968 --- /dev/null +++ b/app/components/ruby_ui/native_select/native_select.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module RubyUI + class NativeSelect < Base + def initialize(size: :default, **attrs) + @size = size + super(**attrs) + end + + def view_template(&block) + div( + class: "group/native-select relative w-fit has-[select:disabled]:opacity-50" + ) do + select(**attrs, &block) + render RubyUI::NativeSelectIcon.new + end + end + + private + + def default_attrs + { + data: { + ruby_ui__form_field_target: "input", + action: "change->ruby-ui--form-field#onChange invalid->ruby-ui--form-field#onInvalid" + }, + class: [ + "border-border bg-transparent text-sm w-full min-w-0 appearance-none rounded-md border py-1 pr-8 pl-2.5 shadow-xs transition-[color,box-shadow] outline-none select-none ring-0 ring-ring/0", + "placeholder:text-muted-foreground", + "selection:bg-primary selection:text-primary-foreground", + "focus-visible:outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-2", + "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", + "aria-invalid:ring-destructive/20 aria-invalid:border-destructive aria-invalid:ring-2", + (@size == :sm) ? "h-7 rounded-md py-0.5" : "h-9" + ] + } + end + end +end diff --git a/app/components/ruby_ui/native_select/native_select_group.rb b/app/components/ruby_ui/native_select/native_select_group.rb new file mode 100644 index 00000000..d3fae6d7 --- /dev/null +++ b/app/components/ruby_ui/native_select/native_select_group.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RubyUI + class NativeSelectGroup < Base + def view_template(&) + optgroup(**attrs, &) + end + + private + + def default_attrs + {} + end + end +end diff --git a/app/components/ruby_ui/native_select/native_select_icon.rb b/app/components/ruby_ui/native_select/native_select_icon.rb new file mode 100644 index 00000000..1169df8a --- /dev/null +++ b/app/components/ruby_ui/native_select/native_select_icon.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module RubyUI + class NativeSelectIcon < Base + def view_template(&block) + span(**attrs) do + if block + block.call + else + icon + end + end + end + + private + + def icon + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + stroke_width: "2", + stroke_linecap: "round", + stroke_linejoin: "round", + class: "size-4", + aria_hidden: "true" + ) do |s| + s.path(d: "m6 9 6 6 6-6") + end + end + + def default_attrs + { + class: "text-muted-foreground pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 select-none" + } + end + end +end diff --git a/app/components/ruby_ui/native_select/native_select_option.rb b/app/components/ruby_ui/native_select/native_select_option.rb new file mode 100644 index 00000000..bf4dd3e3 --- /dev/null +++ b/app/components/ruby_ui/native_select/native_select_option.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RubyUI + class NativeSelectOption < Base + def view_template(&) + option(**attrs, &) + end + + private + + def default_attrs + {} + end + end +end diff --git a/app/components/ruby_ui/sheet/sheet_content.rb b/app/components/ruby_ui/sheet/sheet_content.rb index bf3a3115..a097f1e1 100644 --- a/app/components/ruby_ui/sheet/sheet_content.rb +++ b/app/components/ruby_ui/sheet/sheet_content.rb @@ -33,7 +33,7 @@ def default_attrs { data_state: "open", # For animate in class: [ - "fixed pointer-events-auto z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + "fixed pointer-events-auto z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 overflow-scroll", @side_classes ] }