@sigx/zero-daisyui 0.11.0 → 0.12.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.
- package/README.md +5 -0
- package/dist/css/components/radio-group.css +6 -0
- package/dist/css/index.css +6 -0
- package/dist/lynx/components/checkbox.css +4 -2
- package/dist/lynx/components/fieldset.css +10 -1
- package/dist/lynx/components/input.css +40 -2
- package/dist/lynx/components/number-input.css +18 -3
- package/dist/lynx/components/radio-group.css +10 -2
- package/dist/lynx/components/textarea.css +23 -2
- package/dist/lynx/components/toggle-group.css +41 -2
- package/dist/lynx/components/toggle.css +27 -2
- package/dist/lynx/index.css +173 -16
- package/dist/lynx/manifest.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/recipes.js +277 -8
- package/dist/recipes.js.map +1 -1
- package/dist/report.json +0 -12
- package/package.json +4 -4
- package/src/recipes.ts +278 -8
package/dist/recipes.js
CHANGED
|
@@ -1621,6 +1621,10 @@ export const field = {
|
|
|
1621
1621
|
label: {
|
|
1622
1622
|
base: { fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)', color: 'var(--field-accent)' },
|
|
1623
1623
|
states: { disabled: { opacity: 'var(--disabled-opacity)' } },
|
|
1624
|
+
// lynx has no pseudo-elements and the anatomy no part to carry
|
|
1625
|
+
// the asterisk, so it stays a web-only mark: on lynx a required
|
|
1626
|
+
// field still stamps `required` on its root and label, and the
|
|
1627
|
+
// control inside adopts it (signalxjs/lynx#1205).
|
|
1624
1628
|
selectors: {
|
|
1625
1629
|
'&[data-required]::after': { content: '" *"', color: roleInk('error') },
|
|
1626
1630
|
},
|
|
@@ -1711,6 +1715,33 @@ export const fieldset = {
|
|
|
1711
1715
|
xl: { legend: { base: { fontSize: 'var(--text-lg)' } } },
|
|
1712
1716
|
},
|
|
1713
1717
|
},
|
|
1718
|
+
// Lynx has no grid: the one-column track becomes a flex column (the gap
|
|
1719
|
+
// survives), and the block/inline paddings are restated physically —
|
|
1720
|
+
// logical spellings resolve on iOS but not on Android (signalxjs/lynx#1084).
|
|
1721
|
+
targets: {
|
|
1722
|
+
lynx: {
|
|
1723
|
+
parts: {
|
|
1724
|
+
root: {
|
|
1725
|
+
base: {
|
|
1726
|
+
display: 'flex',
|
|
1727
|
+
flexDirection: 'column',
|
|
1728
|
+
paddingTop: 'var(--space-xs)',
|
|
1729
|
+
paddingBottom: 'var(--space-xs)',
|
|
1730
|
+
paddingLeft: '0',
|
|
1731
|
+
paddingRight: '0',
|
|
1732
|
+
},
|
|
1733
|
+
},
|
|
1734
|
+
legend: {
|
|
1735
|
+
base: {
|
|
1736
|
+
paddingTop: 'var(--space-sm)',
|
|
1737
|
+
paddingBottom: 'var(--space-sm)',
|
|
1738
|
+
paddingLeft: '0',
|
|
1739
|
+
paddingRight: '0',
|
|
1740
|
+
},
|
|
1741
|
+
},
|
|
1742
|
+
},
|
|
1743
|
+
},
|
|
1744
|
+
},
|
|
1714
1745
|
};
|
|
1715
1746
|
/**
|
|
1716
1747
|
* daisy's tick, drawn by a clip-path that GROWS.
|
|
@@ -1939,11 +1970,25 @@ export const checkbox = {
|
|
|
1939
1970
|
targets: {
|
|
1940
1971
|
lynx: {
|
|
1941
1972
|
parts: {
|
|
1973
|
+
// The box/label row, pinned: `inline-flex` is rewritten to
|
|
1974
|
+
// `flex`, and the row must not depend on the engine's
|
|
1975
|
+
// default direction (signalxjs/lynx#1203).
|
|
1976
|
+
root: { base: { display: 'flex', flexDirection: 'row' } },
|
|
1942
1977
|
control: {
|
|
1943
1978
|
// The web fallback (`color-mix(in oklab, … currentColor …)`)
|
|
1944
1979
|
// exists for consumers that unset the accent; this package
|
|
1945
1980
|
// always defines it, so the plain accent IS the ring.
|
|
1946
|
-
|
|
1981
|
+
//
|
|
1982
|
+
// `inline-block` is not a lynx display value (no inline
|
|
1983
|
+
// formatting context); a flex box keeps daisy's geometry —
|
|
1984
|
+
// the padding insets the 100%-sized indicator either way.
|
|
1985
|
+
base: { display: 'flex', border: 'var(--border) solid var(--checkbox-accent)' },
|
|
1986
|
+
// The ring as spread shadows that follow the box's radius
|
|
1987
|
+
// (signalxjs/lynx#1163 — lynx's `outline` ignores it and
|
|
1988
|
+
// has no offset), keeping the box's inset depth line.
|
|
1989
|
+
states: {
|
|
1990
|
+
'focus-visible': lynxFocusRing('var(--checkbox-accent)', { under: '0 1px var(--depth-shade) inset' }),
|
|
1991
|
+
},
|
|
1947
1992
|
},
|
|
1948
1993
|
indicator: {
|
|
1949
1994
|
// The tick's fill: the control's `color:` names
|
|
@@ -1989,6 +2034,11 @@ export const radioGroup = {
|
|
|
1989
2034
|
// `invalid` paints on each `item-control`, which carries the flag
|
|
1990
2035
|
// itself (#267) — the root only groups the items.
|
|
1991
2036
|
states: { invalid: {}, required: {} },
|
|
2037
|
+
// `orientation="horizontal"` lays the items in a wrapping row —
|
|
2038
|
+
// checkbox-group's rule (signalxjs/zero#393).
|
|
2039
|
+
selectors: {
|
|
2040
|
+
'&[data-orientation="horizontal"]': { flexDirection: 'row', flexWrap: 'wrap', columnGap: 'var(--space-lg)' },
|
|
2041
|
+
},
|
|
1992
2042
|
},
|
|
1993
2043
|
label: {
|
|
1994
2044
|
base: { fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)' },
|
|
@@ -2096,9 +2146,20 @@ export const radioGroup = {
|
|
|
2096
2146
|
targets: {
|
|
2097
2147
|
lynx: {
|
|
2098
2148
|
parts: {
|
|
2149
|
+
// The control/label row, pinned — as checkbox's root
|
|
2150
|
+
// (signalxjs/lynx#1203).
|
|
2151
|
+
item: { base: { display: 'flex', flexDirection: 'row' } },
|
|
2099
2152
|
'item-control': {
|
|
2100
|
-
|
|
2101
|
-
|
|
2153
|
+
// `display: flex` in place of `inline-block`, which lynx
|
|
2154
|
+
// does not have — the padding still insets the dot.
|
|
2155
|
+
base: { display: 'flex', border: 'var(--border) solid var(--radio-accent)' },
|
|
2156
|
+
states: {
|
|
2157
|
+
checked: { borderColor: 'var(--radio-accent)' },
|
|
2158
|
+
// The round ring (signalxjs/lynx#1163): spread
|
|
2159
|
+
// shadows follow the 9999px radius where `outline`
|
|
2160
|
+
// drew a square.
|
|
2161
|
+
'focus-visible': lynxFocusRing('var(--radio-accent)', { under: '0 1px var(--depth-shade) inset' }),
|
|
2162
|
+
},
|
|
2102
2163
|
},
|
|
2103
2164
|
'item-indicator': {
|
|
2104
2165
|
states: { checked: { backgroundColor: 'var(--radio-accent)' } },
|
|
@@ -4287,6 +4348,45 @@ export const toggle = {
|
|
|
4287
4348
|
},
|
|
4288
4349
|
},
|
|
4289
4350
|
defaultVariants: { color: 'primary', size: 'md' },
|
|
4351
|
+
// signalxjs/lynx#1204 — the lynx replacements for what this recipe's
|
|
4352
|
+
// shared sections cannot say there.
|
|
4353
|
+
targets: {
|
|
4354
|
+
lynx: {
|
|
4355
|
+
parts: {
|
|
4356
|
+
root: {
|
|
4357
|
+
// daisy's content-sized, never-squeezed btn (lynx#1165):
|
|
4358
|
+
// a lynx view has no inline formatting context, so the
|
|
4359
|
+
// toggle stretched to its column and a squeezed label
|
|
4360
|
+
// wrapped per character. The glyph + label sit in a row.
|
|
4361
|
+
// The hairline as longhands: a var-bearing `border`
|
|
4362
|
+
// shorthand expands after the cascade and would beat
|
|
4363
|
+
// any edge a later rule restates (lynx#1161/#1162).
|
|
4364
|
+
base: {
|
|
4365
|
+
...lynxBtnFit,
|
|
4366
|
+
flexDirection: 'row',
|
|
4367
|
+
border: '0 solid transparent',
|
|
4368
|
+
...lynxSides('border{}Width', 'var(--border)'),
|
|
4369
|
+
...lynxSides('border{}Color', 'var(--color-base-300)'),
|
|
4370
|
+
},
|
|
4371
|
+
states: {
|
|
4372
|
+
// No hover on a touch platform: the held toggle
|
|
4373
|
+
// takes the wash daisy's hover gives it. The shared
|
|
4374
|
+
// pressed rule adds the btn's 1px sink.
|
|
4375
|
+
pressed: { background: 'var(--color-base-300)' },
|
|
4376
|
+
on: lynxSides('border{}Color', 'var(--toggle-accent)'),
|
|
4377
|
+
// lynx's `outline` ignores the radius and has no
|
|
4378
|
+
// offset (lynx#1163): the ring as spread shadows.
|
|
4379
|
+
'focus-visible': lynxFocusRing('var(--toggle-accent)'),
|
|
4380
|
+
},
|
|
4381
|
+
selectors: {
|
|
4382
|
+
// A held on toggle keeps its fill (the web's
|
|
4383
|
+
// `[data-state=on]:hover` stays on the accent too).
|
|
4384
|
+
'&[data-state="on"][data-pressed]': { background: 'var(--toggle-accent)' },
|
|
4385
|
+
},
|
|
4386
|
+
},
|
|
4387
|
+
},
|
|
4388
|
+
},
|
|
4389
|
+
},
|
|
4290
4390
|
};
|
|
4291
4391
|
// daisy "join" of btns: one bordered capsule, hairline seams between items,
|
|
4292
4392
|
// the on item filled with the accent.
|
|
@@ -4395,6 +4495,65 @@ export const toggleGroup = {
|
|
|
4395
4495
|
])),
|
|
4396
4496
|
},
|
|
4397
4497
|
defaultVariants: { color: 'primary' },
|
|
4498
|
+
// signalxjs/lynx#1204 — the lynx replacements for what this recipe's
|
|
4499
|
+
// shared sections cannot say there.
|
|
4500
|
+
targets: {
|
|
4501
|
+
lynx: {
|
|
4502
|
+
parts: {
|
|
4503
|
+
root: {
|
|
4504
|
+
// Content-sized like the web's inline-flex capsule (a
|
|
4505
|
+
// lynx view stretches to its column otherwise), a row
|
|
4506
|
+
// unless vertical, and the frame as longhands so the
|
|
4507
|
+
// orientation rules below can drop one edge by
|
|
4508
|
+
// specificity (a var-bearing `border` shorthand would
|
|
4509
|
+
// expand over them, lynx#1161/#1162).
|
|
4510
|
+
base: {
|
|
4511
|
+
width: 'max-content',
|
|
4512
|
+
flexShrink: '0',
|
|
4513
|
+
flexDirection: 'row',
|
|
4514
|
+
border: '0 solid transparent',
|
|
4515
|
+
...lynxSides('border{}Width', 'var(--border)'),
|
|
4516
|
+
...lynxSides('border{}Color', 'var(--color-base-300)'),
|
|
4517
|
+
},
|
|
4518
|
+
selectors: {
|
|
4519
|
+
// The join seams: lynx has no sibling combinator, so
|
|
4520
|
+
// the web's `item + item` edge cannot be selected.
|
|
4521
|
+
// Every item draws its leading seam instead (below),
|
|
4522
|
+
// and the frame gives up that edge — the first item's
|
|
4523
|
+
// seam stands in for it, inside the frame's clip.
|
|
4524
|
+
'&[data-orientation="horizontal"]': { borderLeftWidth: '0' },
|
|
4525
|
+
'&[data-orientation="vertical"]': { borderTopWidth: '0' },
|
|
4526
|
+
},
|
|
4527
|
+
},
|
|
4528
|
+
item: {
|
|
4529
|
+
base: { flexShrink: '0', flexWrap: 'nowrap' },
|
|
4530
|
+
states: {
|
|
4531
|
+
// No hover on a touch platform: a held item takes the
|
|
4532
|
+
// wash daisy's hover gives it; an on item keeps its
|
|
4533
|
+
// fill (the selector below).
|
|
4534
|
+
pressed: { background: 'var(--color-base-300)' },
|
|
4535
|
+
// The frame clips its items, so the ring is drawn
|
|
4536
|
+
// inside the item (lynx's `outline` has no offset
|
|
4537
|
+
// and ignores the radius, lynx#1163).
|
|
4538
|
+
'focus-visible': lynxFocusRing('var(--toggle-group-accent)', { inset: true }),
|
|
4539
|
+
},
|
|
4540
|
+
selectors: {
|
|
4541
|
+
'&[data-state="on"][data-pressed]': { background: 'var(--toggle-group-accent)' },
|
|
4542
|
+
'&[data-orientation="horizontal"]': {
|
|
4543
|
+
borderLeftWidth: 'var(--border)',
|
|
4544
|
+
borderLeftStyle: 'solid',
|
|
4545
|
+
borderLeftColor: 'var(--color-base-300)',
|
|
4546
|
+
},
|
|
4547
|
+
'&[data-orientation="vertical"]': {
|
|
4548
|
+
borderTopWidth: 'var(--border)',
|
|
4549
|
+
borderTopStyle: 'solid',
|
|
4550
|
+
borderTopColor: 'var(--color-base-300)',
|
|
4551
|
+
},
|
|
4552
|
+
},
|
|
4553
|
+
},
|
|
4554
|
+
},
|
|
4555
|
+
},
|
|
4556
|
+
},
|
|
4398
4557
|
};
|
|
4399
4558
|
// daisy "join" of an input and two btns: one bordered capsule (the control),
|
|
4400
4559
|
// hairline seams on the triggers' inner edges, neutral btn fills for the steppers.
|
|
@@ -4538,14 +4697,53 @@ export const numberInput = {
|
|
|
4538
4697
|
xl: { control: { base: { height: fieldHeight('xl') } }, input: { base: { fontSize: 'var(--text-lg)', padding: 'var(--space-lg) var(--space-xl)' } } },
|
|
4539
4698
|
},
|
|
4540
4699
|
},
|
|
4541
|
-
//
|
|
4542
|
-
//
|
|
4543
|
-
//
|
|
4700
|
+
// Lynx restatements:
|
|
4701
|
+
// - the steppers' inline padding and their seams, physically: logical
|
|
4702
|
+
// spellings resolve on iOS but not on Android (measured,
|
|
4703
|
+
// signalxjs/lynx#1084);
|
|
4704
|
+
// - the steppers are views around a text glyph, with none of a
|
|
4705
|
+
// button's content centering;
|
|
4706
|
+
// - the native input takes no `inherit`: its ink is spelled out, and it
|
|
4707
|
+
// grows into any room a stretched control leaves between the steppers;
|
|
4708
|
+
// - the web root is inline-flex and hugs its content; lynx's flex column
|
|
4709
|
+
// stretches, so the children align to the start instead;
|
|
4710
|
+
// - the focus ring is `lynxFocusRing` (lynx's outline ignores the radius
|
|
4711
|
+
// and has no offset, signalxjs/lynx#1163). A shadow must not be
|
|
4712
|
+
// clipped by the box's own `overflow: hidden`, so the control stops
|
|
4713
|
+
// clipping and the steppers round their own outer corners instead.
|
|
4544
4714
|
targets: {
|
|
4545
4715
|
lynx: {
|
|
4546
4716
|
parts: {
|
|
4547
|
-
|
|
4548
|
-
|
|
4717
|
+
root: { base: { alignItems: 'flex-start' } },
|
|
4718
|
+
control: {
|
|
4719
|
+
base: { overflow: 'visible' },
|
|
4720
|
+
states: { 'focus-visible': lynxFocusRing('var(--number-input-accent)') },
|
|
4721
|
+
},
|
|
4722
|
+
input: { base: { color: 'var(--color-base-content)', flexGrow: '1' } },
|
|
4723
|
+
'increment-trigger': {
|
|
4724
|
+
base: {
|
|
4725
|
+
display: 'flex',
|
|
4726
|
+
alignItems: 'center',
|
|
4727
|
+
justifyContent: 'center',
|
|
4728
|
+
paddingLeft: 'var(--space-lg)',
|
|
4729
|
+
paddingRight: 'var(--space-lg)',
|
|
4730
|
+
borderLeft: 'var(--border) solid var(--color-base-300)',
|
|
4731
|
+
borderTopRightRadius: 'var(--radius-field)',
|
|
4732
|
+
borderBottomRightRadius: 'var(--radius-field)',
|
|
4733
|
+
},
|
|
4734
|
+
},
|
|
4735
|
+
'decrement-trigger': {
|
|
4736
|
+
base: {
|
|
4737
|
+
display: 'flex',
|
|
4738
|
+
alignItems: 'center',
|
|
4739
|
+
justifyContent: 'center',
|
|
4740
|
+
paddingLeft: 'var(--space-lg)',
|
|
4741
|
+
paddingRight: 'var(--space-lg)',
|
|
4742
|
+
borderRight: 'var(--border) solid var(--color-base-300)',
|
|
4743
|
+
borderTopLeftRadius: 'var(--radius-field)',
|
|
4744
|
+
borderBottomLeftRadius: 'var(--radius-field)',
|
|
4745
|
+
},
|
|
4746
|
+
},
|
|
4549
4747
|
},
|
|
4550
4748
|
},
|
|
4551
4749
|
},
|
|
@@ -4948,6 +5146,14 @@ const affixSize = (fontSize) => ({
|
|
|
4948
5146
|
'clear-trigger': { base: { fontSize } },
|
|
4949
5147
|
'visibility-trigger': { base: { fontSize } },
|
|
4950
5148
|
});
|
|
5149
|
+
/**
|
|
5150
|
+
* A text field's placeholder ink on lynx (signalxjs/lynx#1205): the web's
|
|
5151
|
+
* `::placeholder` mix, for lynx's `-x-placeholder-color` property — the
|
|
5152
|
+
* emitter bakes the `color-mix()` to one literal per theme.
|
|
5153
|
+
*/
|
|
5154
|
+
const textFieldPlaceholder = 'color-mix(in oklab, var(--color-base-content) 60%, transparent)';
|
|
5155
|
+
/** The ghost field button's held look on lynx — the web's hover wash, on a press. */
|
|
5156
|
+
const fieldButtonHeld = { color: 'var(--color-base-content)', background: 'var(--color-base-200)' };
|
|
4951
5157
|
/**
|
|
4952
5158
|
* daisy "input" flavor: the shared field box with nothing in it but the text.
|
|
4953
5159
|
* Same `fieldControl` metrics as select's trigger, combobox's control and the
|
|
@@ -5069,6 +5275,53 @@ export const input = {
|
|
|
5069
5275
|
xl: { control: { base: { height: fieldHeight('xl') } }, input: { base: { fontSize: 'var(--text-lg)', padding: 'var(--space-lg) var(--space-xl)' } }, ...affixSize('var(--text-lg)') },
|
|
5070
5276
|
},
|
|
5071
5277
|
},
|
|
5278
|
+
// lynx (signalxjs/lynx#1205). The field is a native text widget inside
|
|
5279
|
+
// a view `control`, so what the web gets from the cascade is restated:
|
|
5280
|
+
targets: {
|
|
5281
|
+
lynx: {
|
|
5282
|
+
parts: {
|
|
5283
|
+
// The web control is an `inline-flex` row; the emitter's
|
|
5284
|
+
// `flex` rewrite keeps no direction, so the row is explicit.
|
|
5285
|
+
// No `:hover` border on a touch platform — the ring below
|
|
5286
|
+
// (box-shadow spread, signalxjs/lynx#1163) is the focus cue,
|
|
5287
|
+
// in the root's accent like the web outline.
|
|
5288
|
+
control: {
|
|
5289
|
+
base: { flexDirection: 'row' },
|
|
5290
|
+
states: { 'focus-visible': lynxFocusRing('var(--input-accent)') },
|
|
5291
|
+
},
|
|
5292
|
+
// `color: inherit` never reaches a native text field, and
|
|
5293
|
+
// `::placeholder` does not exist: the ink is explicit and the
|
|
5294
|
+
// placeholder takes lynx's own `-x-placeholder-color`, the
|
|
5295
|
+
// web's 60% mix baked per theme.
|
|
5296
|
+
input: {
|
|
5297
|
+
base: {
|
|
5298
|
+
color: 'var(--color-base-content)',
|
|
5299
|
+
'-x-placeholder-color': textFieldPlaceholder,
|
|
5300
|
+
flexGrow: '1',
|
|
5301
|
+
flexShrink: '1',
|
|
5302
|
+
},
|
|
5303
|
+
},
|
|
5304
|
+
// The adornment's edge padding, physical: Android never
|
|
5305
|
+
// resolves the logical spellings (signalxjs/lynx#1084).
|
|
5306
|
+
adornment: {
|
|
5307
|
+
selectors: {
|
|
5308
|
+
'&[data-placement="start"]': { paddingLeft: 'var(--space-md)' },
|
|
5309
|
+
'&[data-placement="end"]': { paddingRight: 'var(--space-md)' },
|
|
5310
|
+
},
|
|
5311
|
+
},
|
|
5312
|
+
// Same for the ghost buttons' end margin; the web's `:hover`
|
|
5313
|
+
// wash answers a press instead.
|
|
5314
|
+
'clear-trigger': {
|
|
5315
|
+
base: { marginRight: 'var(--space-xs)' },
|
|
5316
|
+
states: { pressed: fieldButtonHeld },
|
|
5317
|
+
},
|
|
5318
|
+
'visibility-trigger': {
|
|
5319
|
+
base: { marginRight: 'var(--space-xs)' },
|
|
5320
|
+
states: { pressed: fieldButtonHeld },
|
|
5321
|
+
},
|
|
5322
|
+
},
|
|
5323
|
+
},
|
|
5324
|
+
},
|
|
5072
5325
|
};
|
|
5073
5326
|
/**
|
|
5074
5327
|
* daisy "textarea" flavor. The `fieldControl` box minus its `height`: the
|
|
@@ -5136,6 +5389,22 @@ export const textarea = {
|
|
|
5136
5389
|
xl: { textarea: { base: { fontSize: 'var(--text-lg)', minHeight: `calc(${fieldHeight('xl')} * 2)`, padding: 'var(--space-lg) var(--space-xl)' } } },
|
|
5137
5390
|
},
|
|
5138
5391
|
},
|
|
5392
|
+
// lynx (signalxjs/lynx#1205): lynx-zero renders the part as a view (the
|
|
5393
|
+
// box, whose state classes repaint) around the native field, which wears
|
|
5394
|
+
// the part's base class as its text face. So the ink and the placeholder
|
|
5395
|
+
// are explicit here — `color: inherit` and `::placeholder` never reach a
|
|
5396
|
+
// native widget — and the web's `:hover` border and outline ring become
|
|
5397
|
+
// the lynx focus ring in the root's accent (signalxjs/lynx#1163).
|
|
5398
|
+
targets: {
|
|
5399
|
+
lynx: {
|
|
5400
|
+
parts: {
|
|
5401
|
+
textarea: {
|
|
5402
|
+
base: { color: 'var(--color-base-content)', '-x-placeholder-color': textFieldPlaceholder },
|
|
5403
|
+
states: { 'focus-visible': lynxFocusRing('var(--textarea-accent)') },
|
|
5404
|
+
},
|
|
5405
|
+
},
|
|
5406
|
+
},
|
|
5407
|
+
},
|
|
5139
5408
|
};
|
|
5140
5409
|
// ── Content tier (#311) ───────────────────────────────────────────────────
|
|
5141
5410
|
/**
|