luxen-ui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/cdn/custom-elements.json +495 -337
  2. package/cdn/elements/dialog/dialog.d.ts +3 -0
  3. package/cdn/elements/dialog/dialog.d.ts.map +1 -1
  4. package/cdn/elements/dialog/dialog.js +10 -6
  5. package/cdn/elements/dialog/dialog.js.map +1 -1
  6. package/cdn/elements/dialog/dialog.styles.js +1 -1
  7. package/cdn/elements/dialog/dialog.styles.js.map +1 -1
  8. package/cdn/elements/dropdown/dropdown.js +1 -1
  9. package/cdn/elements/dropdown/dropdown.js.map +1 -1
  10. package/cdn/elements/dropdown-item/dropdown-item.js +1 -1
  11. package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
  12. package/cdn/elements/input-otp/input-otp.d.ts +8 -2
  13. package/cdn/elements/input-otp/input-otp.d.ts.map +1 -1
  14. package/cdn/elements/input-otp/input-otp.js +1 -1
  15. package/cdn/elements/input-otp/input-otp.js.map +1 -1
  16. package/cdn/elements/popover/popover.js +1 -1
  17. package/cdn/elements/popover/popover.js.map +1 -1
  18. package/cdn/styles/elements/button.css +1 -1
  19. package/cdn/styles/elements/input-otp.css +63 -29
  20. package/cdn/styles/index.css +15 -2
  21. package/dist/css/elements/button.css +1 -1
  22. package/dist/css/elements/input-otp.css +63 -29
  23. package/dist/css/index.css +15 -2
  24. package/dist/custom-elements.json +495 -337
  25. package/dist/elements/dialog/dialog.css +10 -0
  26. package/dist/elements/dialog/dialog.d.ts +3 -0
  27. package/dist/elements/dialog/dialog.d.ts.map +1 -1
  28. package/dist/elements/dialog/dialog.js +16 -4
  29. package/dist/elements/dropdown/dropdown.css +4 -4
  30. package/dist/elements/dropdown-item/dropdown-item.css +2 -1
  31. package/dist/elements/input-otp/input-otp.d.ts +8 -2
  32. package/dist/elements/input-otp/input-otp.d.ts.map +1 -1
  33. package/dist/elements/input-otp/input-otp.js +14 -5
  34. package/dist/elements/popover/popover.css +3 -4
  35. package/dist/skills/luxen-ui/references/dialog.md +79 -1
  36. package/dist/skills/luxen-ui/references/drawer.md +8 -0
  37. package/package.json +1 -1
@@ -15,13 +15,14 @@
15
15
 
16
16
  l-input-otp {
17
17
  --digits: 6;
18
- --size: 2.75rem;
19
- --_font-size: calc(var(--size) * 0.45);
20
- --_bg: color-mix(in oklab, var(--l-color-text-primary) 4%, var(--l-color-surface));
21
- --_border-color: var(--l-color-border);
22
- --_highlight-color: var(--l-focus-ring);
18
+ --cell-size: 2.75rem;
19
+ --cell-bg-color: color-mix(in oklab, var(--l-color-text-primary) 4%, var(--l-color-surface));
20
+ --cell-border-color: var(--l-color-border);
21
+ --cell-border-radius: var(--radius-md);
22
+ --cell-focus-color: var(--l-focus-ring);
23
+ --cell-focus-ring: 0 0 0 1px var(--cell-focus-color);
23
24
 
24
- display: inline-flex;
25
+ display: inline-block;
25
26
  position: relative;
26
27
  }
27
28
 
@@ -34,7 +35,7 @@
34
35
  .l-input-otp-cells {
35
36
  display: inline-flex;
36
37
  align-items: center;
37
- gap: var(--gap, 0.5rem);
38
+ gap: var(--cell-gap, 0.5rem);
38
39
  position: relative;
39
40
  }
40
41
 
@@ -48,15 +49,15 @@
48
49
  display: flex;
49
50
  align-items: center;
50
51
  justify-content: center;
51
- inline-size: var(--size);
52
- block-size: var(--size);
53
- border: 1px solid var(--_border-color);
54
- border-radius: var(--radius-md);
55
- background: var(--_bg);
52
+ inline-size: var(--cell-size);
53
+ block-size: var(--cell-size);
54
+ border: 1px solid var(--cell-border-color);
55
+ border-radius: var(--cell-border-radius);
56
+ background: var(--cell-bg-color);
56
57
  font-family:
57
58
  ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
58
59
  monospace;
59
- font-size: var(--_font-size);
60
+ font-size: calc(var(--cell-size) * 0.45);
60
61
  font-variant-numeric: tabular-nums;
61
62
  line-height: 1;
62
63
  color: var(--l-color-text-primary);
@@ -73,8 +74,37 @@
73
74
  */
74
75
 
75
76
  l-input-otp:focus-within .l-input-otp-cell[data-active] {
76
- border-color: var(--_highlight-color);
77
- box-shadow: 0 0 0 1px var(--_highlight-color);
77
+ border-color: var(--cell-focus-color);
78
+ box-shadow: var(--cell-focus-ring);
79
+ }
80
+
81
+ /*
82
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
83
+ 🅲🅰🆁🅴🆃 (fake blinking caret in active empty cell)
84
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
85
+ The native caret is hidden via `caret-color: transparent`; this stand-in
86
+ gives the missing point-of-insertion cue inside the active cell. Only
87
+ visible while empty — once a digit is typed, it replaces the caret.
88
+ */
89
+
90
+ l-input-otp:focus-within .l-input-otp-cell[data-active]:not([data-filled])::after {
91
+ content: '';
92
+ inline-size: 1px;
93
+ block-size: 1em;
94
+ background: currentColor;
95
+ animation: l-input-otp-caret 1s steps(2, jump-none) infinite;
96
+ }
97
+
98
+ @keyframes l-input-otp-caret {
99
+ 50% {
100
+ opacity: 0;
101
+ }
102
+ }
103
+
104
+ @media (prefers-reduced-motion: reduce) {
105
+ l-input-otp:focus-within .l-input-otp-cell[data-active]:not([data-filled])::after {
106
+ animation: none;
107
+ }
78
108
  }
79
109
 
80
110
  /*
@@ -122,11 +152,11 @@
122
152
  */
123
153
 
124
154
  l-input-otp[size='sm'] {
125
- --size: 2rem;
155
+ --cell-size: 2rem;
126
156
  }
127
157
 
128
158
  l-input-otp[size='lg'] {
129
- --size: 3.5rem;
159
+ --cell-size: 3.5rem;
130
160
  }
131
161
 
132
162
  /*
@@ -145,20 +175,24 @@
145
175
  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
146
176
  🅿🆁🅾🅶🆁🅴🆂🆂🅸🆅🅴 🅴🅽🅷🅰🅽🅲🅴🅼🅴🅽🆃 🅵🅰🅻🅻🅱🅰🅲🅺
147
177
  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
148
- Before JS loads, the raw input is visible and usable.
178
+ Pre-upgrade reserves the exact box the cells will occupy width scales
179
+ with --digits / --cell-size / --cell-gap so layout doesn't shift on hydration.
180
+ Single soft-tinted rectangle (not per-cell): matches any custom appearance
181
+ cleanly since it doesn't pretend to redraw the cell layout.
149
182
  */
150
183
 
151
- l-input-otp:not(:defined) > input {
152
- all: unset;
184
+ l-input-otp:not(:defined) {
153
185
  display: inline-block;
154
- border: 1px solid var(--l-color-border);
155
- border-radius: var(--radius-md);
156
- padding: 0.5rem 0.75rem;
157
- font-family:
158
- ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
159
- monospace;
160
- font-size: 1.25rem;
161
- letter-spacing: 0.5ch;
162
- color: var(--l-color-text-primary);
186
+ flex-shrink: 0;
187
+ inline-size: calc(
188
+ var(--cell-size) * var(--digits) + var(--cell-gap, 0.5rem) * (var(--digits) - 1)
189
+ );
190
+ block-size: var(--cell-size);
191
+ background: var(--cell-bg-color);
192
+ border-radius: var(--cell-border-radius);
193
+ }
194
+
195
+ l-input-otp:not(:defined) > input {
196
+ display: none;
163
197
  }
164
198
  }
@@ -707,6 +707,16 @@ In dark mode, mixes the base color with black (default 15% black).
707
707
  white-space: nowrap;
708
708
  border: 0;
709
709
  }
710
+
711
+ /* Hide Shadow-DOM overlay elements until their custom element upgrades.
712
+ Without this, slotted/inner content flashes inline before the upgrade. */
713
+ l-dialog:not(:defined),
714
+ l-drawer:not(:defined),
715
+ l-dropdown:not(:defined),
716
+ l-popover:not(:defined),
717
+ l-tooltip:not(:defined) {
718
+ display: none;
719
+ }
710
720
  }
711
721
 
712
722
  /* https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/theme.css */
@@ -757,8 +767,8 @@ In dark mode, mixes the base color with black (default 15% black).
757
767
  /* Semi-transparent backdrop behind modals, dialogs, drawers, and any overlay that dims the page content. Darker in dark mode for better contrast against dark surfaces. */
758
768
  --l-backdrop: light-dark(oklch(46% 0.01 260 / 33%), oklch(15% 0.01 260 / 60%));
759
769
 
760
- /* Default border for form controls, secondary buttons, inputs, and selects. */
761
- --l-color-border: light-dark(var(--color-gray-400), var(--color-gray-800));
770
+ /* Default border for form controls, secondary buttons, inputs, selects, and any element that needs a thin neutral outline. Visible enough to delimit the element without competing with surrounding content. */
771
+ --l-color-border: light-dark(var(--color-gray-300), var(--color-gray-600));
762
772
 
763
773
  /* Subtle divider line for separating content sections, list items, and card groups. Lighter than --l-color-border to avoid visual competition with interactive element borders. */
764
774
  --l-color-divider: light-dark(var(--color-gray-200), var(--color-gray-700));
@@ -766,6 +776,9 @@ In dark mode, mixes the base color with black (default 15% black).
766
776
  /* Subtle border or ring for interactive elements like close buttons, toggles, and icon buttons on hover. Provides low-contrast visual feedback without competing with primary content. */
767
777
  --l-color-border-interactive: light-dark(var(--color-gray-300), var(--color-gray-600));
768
778
 
779
+ /* Border for floating surfaces like popovers, dropdowns, menus, tooltips, and combobox listboxes. Aliases --l-color-border so overlays stay visually consistent with form controls, but exposed as a separate semantic so consumers can soften overlay borders independently if needed. Pairs with --l-color-surface-overlay. */
780
+ --l-color-border-overlay: var(--l-color-border);
781
+
769
782
  /* Border color for disabled form controls, buttons, and interactive elements. Faded to signal non-interactivity. */
770
783
  --l-color-border-disabled: light-dark(var(--color-gray-300), var(--color-gray-700));
771
784
 
@@ -24,7 +24,7 @@
24
24
  var(--l-color-text-primary)
25
25
  );
26
26
  --background-color-hover: var(--background-color-active);
27
- --font-size: var(--text-md);
27
+ --font-size: var(--text-sm);
28
28
  --text-color: var(--l-color-text-primary);
29
29
  --text-color-hover: var(--text-color);
30
30
  --border-color: var(--l-color-border);
@@ -15,13 +15,14 @@
15
15
 
16
16
  l-input-otp {
17
17
  --digits: 6;
18
- --size: 2.75rem;
19
- --_font-size: calc(var(--size) * 0.45);
20
- --_bg: color-mix(in oklab, var(--l-color-text-primary) 4%, var(--l-color-surface));
21
- --_border-color: var(--l-color-border);
22
- --_highlight-color: var(--l-focus-ring);
18
+ --cell-size: 2.75rem;
19
+ --cell-bg-color: color-mix(in oklab, var(--l-color-text-primary) 4%, var(--l-color-surface));
20
+ --cell-border-color: var(--l-color-border);
21
+ --cell-border-radius: var(--radius-md);
22
+ --cell-focus-color: var(--l-focus-ring);
23
+ --cell-focus-ring: 0 0 0 1px var(--cell-focus-color);
23
24
 
24
- display: inline-flex;
25
+ display: inline-block;
25
26
  position: relative;
26
27
  }
27
28
 
@@ -34,7 +35,7 @@
34
35
  .l-input-otp-cells {
35
36
  display: inline-flex;
36
37
  align-items: center;
37
- gap: var(--gap, 0.5rem);
38
+ gap: var(--cell-gap, 0.5rem);
38
39
  position: relative;
39
40
  }
40
41
 
@@ -48,15 +49,15 @@
48
49
  display: flex;
49
50
  align-items: center;
50
51
  justify-content: center;
51
- inline-size: var(--size);
52
- block-size: var(--size);
53
- border: 1px solid var(--_border-color);
54
- border-radius: var(--radius-md);
55
- background: var(--_bg);
52
+ inline-size: var(--cell-size);
53
+ block-size: var(--cell-size);
54
+ border: 1px solid var(--cell-border-color);
55
+ border-radius: var(--cell-border-radius);
56
+ background: var(--cell-bg-color);
56
57
  font-family:
57
58
  ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
58
59
  monospace;
59
- font-size: var(--_font-size);
60
+ font-size: calc(var(--cell-size) * 0.45);
60
61
  font-variant-numeric: tabular-nums;
61
62
  line-height: 1;
62
63
  color: var(--l-color-text-primary);
@@ -73,8 +74,37 @@
73
74
  */
74
75
 
75
76
  l-input-otp:focus-within .l-input-otp-cell[data-active] {
76
- border-color: var(--_highlight-color);
77
- box-shadow: 0 0 0 1px var(--_highlight-color);
77
+ border-color: var(--cell-focus-color);
78
+ box-shadow: var(--cell-focus-ring);
79
+ }
80
+
81
+ /*
82
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
83
+ 🅲🅰🆁🅴🆃 (fake blinking caret in active empty cell)
84
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
85
+ The native caret is hidden via `caret-color: transparent`; this stand-in
86
+ gives the missing point-of-insertion cue inside the active cell. Only
87
+ visible while empty — once a digit is typed, it replaces the caret.
88
+ */
89
+
90
+ l-input-otp:focus-within .l-input-otp-cell[data-active]:not([data-filled])::after {
91
+ content: '';
92
+ inline-size: 1px;
93
+ block-size: 1em;
94
+ background: currentColor;
95
+ animation: l-input-otp-caret 1s steps(2, jump-none) infinite;
96
+ }
97
+
98
+ @keyframes l-input-otp-caret {
99
+ 50% {
100
+ opacity: 0;
101
+ }
102
+ }
103
+
104
+ @media (prefers-reduced-motion: reduce) {
105
+ l-input-otp:focus-within .l-input-otp-cell[data-active]:not([data-filled])::after {
106
+ animation: none;
107
+ }
78
108
  }
79
109
 
80
110
  /*
@@ -122,11 +152,11 @@
122
152
  */
123
153
 
124
154
  l-input-otp[size='sm'] {
125
- --size: 2rem;
155
+ --cell-size: 2rem;
126
156
  }
127
157
 
128
158
  l-input-otp[size='lg'] {
129
- --size: 3.5rem;
159
+ --cell-size: 3.5rem;
130
160
  }
131
161
 
132
162
  /*
@@ -145,20 +175,24 @@
145
175
  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
146
176
  🅿🆁🅾🅶🆁🅴🆂🆂🅸🆅🅴 🅴🅽🅷🅰🅽🅲🅴🅼🅴🅽🆃 🅵🅰🅻🅻🅱🅰🅲🅺
147
177
  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
148
- Before JS loads, the raw input is visible and usable.
178
+ Pre-upgrade reserves the exact box the cells will occupy width scales
179
+ with --digits / --cell-size / --cell-gap so layout doesn't shift on hydration.
180
+ Single soft-tinted rectangle (not per-cell): matches any custom appearance
181
+ cleanly since it doesn't pretend to redraw the cell layout.
149
182
  */
150
183
 
151
- l-input-otp:not(:defined) > input {
152
- all: unset;
184
+ l-input-otp:not(:defined) {
153
185
  display: inline-block;
154
- border: 1px solid var(--l-color-border);
155
- border-radius: var(--radius-md);
156
- padding: 0.5rem 0.75rem;
157
- font-family:
158
- ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
159
- monospace;
160
- font-size: 1.25rem;
161
- letter-spacing: 0.5ch;
162
- color: var(--l-color-text-primary);
186
+ flex-shrink: 0;
187
+ inline-size: calc(
188
+ var(--cell-size) * var(--digits) + var(--cell-gap, 0.5rem) * (var(--digits) - 1)
189
+ );
190
+ block-size: var(--cell-size);
191
+ background: var(--cell-bg-color);
192
+ border-radius: var(--cell-border-radius);
193
+ }
194
+
195
+ l-input-otp:not(:defined) > input {
196
+ display: none;
163
197
  }
164
198
  }
@@ -707,6 +707,16 @@ In dark mode, mixes the base color with black (default 15% black).
707
707
  white-space: nowrap;
708
708
  border: 0;
709
709
  }
710
+
711
+ /* Hide Shadow-DOM overlay elements until their custom element upgrades.
712
+ Without this, slotted/inner content flashes inline before the upgrade. */
713
+ l-dialog:not(:defined),
714
+ l-drawer:not(:defined),
715
+ l-dropdown:not(:defined),
716
+ l-popover:not(:defined),
717
+ l-tooltip:not(:defined) {
718
+ display: none;
719
+ }
710
720
  }
711
721
 
712
722
  /* https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/theme.css */
@@ -757,8 +767,8 @@ In dark mode, mixes the base color with black (default 15% black).
757
767
  /* Semi-transparent backdrop behind modals, dialogs, drawers, and any overlay that dims the page content. Darker in dark mode for better contrast against dark surfaces. */
758
768
  --l-backdrop: light-dark(oklch(46% 0.01 260 / 33%), oklch(15% 0.01 260 / 60%));
759
769
 
760
- /* Default border for form controls, secondary buttons, inputs, and selects. */
761
- --l-color-border: light-dark(var(--color-gray-400), var(--color-gray-800));
770
+ /* Default border for form controls, secondary buttons, inputs, selects, and any element that needs a thin neutral outline. Visible enough to delimit the element without competing with surrounding content. */
771
+ --l-color-border: light-dark(var(--color-gray-300), var(--color-gray-600));
762
772
 
763
773
  /* Subtle divider line for separating content sections, list items, and card groups. Lighter than --l-color-border to avoid visual competition with interactive element borders. */
764
774
  --l-color-divider: light-dark(var(--color-gray-200), var(--color-gray-700));
@@ -766,6 +776,9 @@ In dark mode, mixes the base color with black (default 15% black).
766
776
  /* Subtle border or ring for interactive elements like close buttons, toggles, and icon buttons on hover. Provides low-contrast visual feedback without competing with primary content. */
767
777
  --l-color-border-interactive: light-dark(var(--color-gray-300), var(--color-gray-600));
768
778
 
779
+ /* Border for floating surfaces like popovers, dropdowns, menus, tooltips, and combobox listboxes. Aliases --l-color-border so overlays stay visually consistent with form controls, but exposed as a separate semantic so consumers can soften overlay borders independently if needed. Pairs with --l-color-surface-overlay. */
780
+ --l-color-border-overlay: var(--l-color-border);
781
+
769
782
  /* Border color for disabled form controls, buttons, and interactive elements. Faded to signal non-interactivity. */
770
783
  --l-color-border-disabled: light-dark(var(--color-gray-300), var(--color-gray-700));
771
784