@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/report.json
CHANGED
|
@@ -10408,12 +10408,6 @@
|
|
|
10408
10408
|
"detail": "rewritten to px at 16px/rem — lynx resolves rem against its 14px default page font size (measured, signalxjs/lynx#1183), which would draw every rem-based size 12.5% small",
|
|
10409
10409
|
"scope": "menu"
|
|
10410
10410
|
},
|
|
10411
|
-
{
|
|
10412
|
-
"where": "lynx recipe for \"checkbox\".\"root\"",
|
|
10413
|
-
"what": "display: inline-flex",
|
|
10414
|
-
"detail": "rewritten to display: flex — lynx has no inline formatting context, and an unsupported display value keeps the default linear layout (signalxjs/lynx#1075)",
|
|
10415
|
-
"scope": "checkbox"
|
|
10416
|
-
},
|
|
10417
10411
|
{
|
|
10418
10412
|
"where": "lynx recipe for \"checkbox\"",
|
|
10419
10413
|
"what": "--checkbox-size",
|
|
@@ -10426,12 +10420,6 @@
|
|
|
10426
10420
|
"detail": "rewritten to px at 16px/rem — lynx resolves rem against its 14px default page font size (measured, signalxjs/lynx#1183), which would draw every rem-based size 12.5% small",
|
|
10427
10421
|
"scope": "checkbox"
|
|
10428
10422
|
},
|
|
10429
|
-
{
|
|
10430
|
-
"where": "lynx recipe for \"radio-group\".\"item\"",
|
|
10431
|
-
"what": "display: inline-flex",
|
|
10432
|
-
"detail": "rewritten to display: flex — lynx has no inline formatting context, and an unsupported display value keeps the default linear layout (signalxjs/lynx#1075)",
|
|
10433
|
-
"scope": "radio-group"
|
|
10434
|
-
},
|
|
10435
10423
|
{
|
|
10436
10424
|
"where": "lynx recipe for \"radio-group\"",
|
|
10437
10425
|
"what": "--radio-size",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigx/zero-daisyui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "DaisyUI-flavored design system for SignalX Zero — daisy's token values and component look as a pure tokens+recipes skin over @sigx/zero primitives. No Tailwind, no daisyUI plugin required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
"url": "https://github.com/signalxjs/zero/issues"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"@sigx/zero": "^0.
|
|
65
|
+
"@sigx/zero": "^0.12.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"typescript": "^7.0.2",
|
|
69
|
-
"@sigx/zero": "^0.
|
|
70
|
-
"@sigx/zero-kit": "^0.
|
|
69
|
+
"@sigx/zero": "^0.12.0",
|
|
70
|
+
"@sigx/zero-kit": "^0.12.0"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"access": "public"
|
package/src/recipes.ts
CHANGED
|
@@ -1690,6 +1690,10 @@ export const field: RecipeInput = {
|
|
|
1690
1690
|
label: {
|
|
1691
1691
|
base: { fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)', color: 'var(--field-accent)' },
|
|
1692
1692
|
states: { disabled: { opacity: 'var(--disabled-opacity)' } },
|
|
1693
|
+
// lynx has no pseudo-elements and the anatomy no part to carry
|
|
1694
|
+
// the asterisk, so it stays a web-only mark: on lynx a required
|
|
1695
|
+
// field still stamps `required` on its root and label, and the
|
|
1696
|
+
// control inside adopts it (signalxjs/lynx#1205).
|
|
1693
1697
|
selectors: {
|
|
1694
1698
|
'&[data-required]::after': { content: '" *"', color: roleInk('error') },
|
|
1695
1699
|
},
|
|
@@ -1781,6 +1785,33 @@ export const fieldset: RecipeInput = {
|
|
|
1781
1785
|
xl: { legend: { base: { fontSize: 'var(--text-lg)' } } },
|
|
1782
1786
|
},
|
|
1783
1787
|
},
|
|
1788
|
+
// Lynx has no grid: the one-column track becomes a flex column (the gap
|
|
1789
|
+
// survives), and the block/inline paddings are restated physically —
|
|
1790
|
+
// logical spellings resolve on iOS but not on Android (signalxjs/lynx#1084).
|
|
1791
|
+
targets: {
|
|
1792
|
+
lynx: {
|
|
1793
|
+
parts: {
|
|
1794
|
+
root: {
|
|
1795
|
+
base: {
|
|
1796
|
+
display: 'flex',
|
|
1797
|
+
flexDirection: 'column',
|
|
1798
|
+
paddingTop: 'var(--space-xs)',
|
|
1799
|
+
paddingBottom: 'var(--space-xs)',
|
|
1800
|
+
paddingLeft: '0',
|
|
1801
|
+
paddingRight: '0',
|
|
1802
|
+
},
|
|
1803
|
+
},
|
|
1804
|
+
legend: {
|
|
1805
|
+
base: {
|
|
1806
|
+
paddingTop: 'var(--space-sm)',
|
|
1807
|
+
paddingBottom: 'var(--space-sm)',
|
|
1808
|
+
paddingLeft: '0',
|
|
1809
|
+
paddingRight: '0',
|
|
1810
|
+
},
|
|
1811
|
+
},
|
|
1812
|
+
},
|
|
1813
|
+
},
|
|
1814
|
+
},
|
|
1784
1815
|
};
|
|
1785
1816
|
|
|
1786
1817
|
/**
|
|
@@ -2012,11 +2043,25 @@ export const checkbox: RecipeInput = {
|
|
|
2012
2043
|
targets: {
|
|
2013
2044
|
lynx: {
|
|
2014
2045
|
parts: {
|
|
2046
|
+
// The box/label row, pinned: `inline-flex` is rewritten to
|
|
2047
|
+
// `flex`, and the row must not depend on the engine's
|
|
2048
|
+
// default direction (signalxjs/lynx#1203).
|
|
2049
|
+
root: { base: { display: 'flex', flexDirection: 'row' } },
|
|
2015
2050
|
control: {
|
|
2016
2051
|
// The web fallback (`color-mix(in oklab, … currentColor …)`)
|
|
2017
2052
|
// exists for consumers that unset the accent; this package
|
|
2018
2053
|
// always defines it, so the plain accent IS the ring.
|
|
2019
|
-
|
|
2054
|
+
//
|
|
2055
|
+
// `inline-block` is not a lynx display value (no inline
|
|
2056
|
+
// formatting context); a flex box keeps daisy's geometry —
|
|
2057
|
+
// the padding insets the 100%-sized indicator either way.
|
|
2058
|
+
base: { display: 'flex', border: 'var(--border) solid var(--checkbox-accent)' },
|
|
2059
|
+
// The ring as spread shadows that follow the box's radius
|
|
2060
|
+
// (signalxjs/lynx#1163 — lynx's `outline` ignores it and
|
|
2061
|
+
// has no offset), keeping the box's inset depth line.
|
|
2062
|
+
states: {
|
|
2063
|
+
'focus-visible': lynxFocusRing('var(--checkbox-accent)', { under: '0 1px var(--depth-shade) inset' }),
|
|
2064
|
+
},
|
|
2020
2065
|
},
|
|
2021
2066
|
indicator: {
|
|
2022
2067
|
// The tick's fill: the control's `color:` names
|
|
@@ -2064,6 +2109,11 @@ export const radioGroup: RecipeInput = {
|
|
|
2064
2109
|
// `invalid` paints on each `item-control`, which carries the flag
|
|
2065
2110
|
// itself (#267) — the root only groups the items.
|
|
2066
2111
|
states: { invalid: {}, required: {} },
|
|
2112
|
+
// `orientation="horizontal"` lays the items in a wrapping row —
|
|
2113
|
+
// checkbox-group's rule (signalxjs/zero#393).
|
|
2114
|
+
selectors: {
|
|
2115
|
+
'&[data-orientation="horizontal"]': { flexDirection: 'row', flexWrap: 'wrap', columnGap: 'var(--space-lg)' },
|
|
2116
|
+
},
|
|
2067
2117
|
},
|
|
2068
2118
|
label: {
|
|
2069
2119
|
base: { fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-semibold)' },
|
|
@@ -2171,9 +2221,20 @@ export const radioGroup: RecipeInput = {
|
|
|
2171
2221
|
targets: {
|
|
2172
2222
|
lynx: {
|
|
2173
2223
|
parts: {
|
|
2224
|
+
// The control/label row, pinned — as checkbox's root
|
|
2225
|
+
// (signalxjs/lynx#1203).
|
|
2226
|
+
item: { base: { display: 'flex', flexDirection: 'row' } },
|
|
2174
2227
|
'item-control': {
|
|
2175
|
-
|
|
2176
|
-
|
|
2228
|
+
// `display: flex` in place of `inline-block`, which lynx
|
|
2229
|
+
// does not have — the padding still insets the dot.
|
|
2230
|
+
base: { display: 'flex', border: 'var(--border) solid var(--radio-accent)' },
|
|
2231
|
+
states: {
|
|
2232
|
+
checked: { borderColor: 'var(--radio-accent)' },
|
|
2233
|
+
// The round ring (signalxjs/lynx#1163): spread
|
|
2234
|
+
// shadows follow the 9999px radius where `outline`
|
|
2235
|
+
// drew a square.
|
|
2236
|
+
'focus-visible': lynxFocusRing('var(--radio-accent)', { under: '0 1px var(--depth-shade) inset' }),
|
|
2237
|
+
},
|
|
2177
2238
|
},
|
|
2178
2239
|
'item-indicator': {
|
|
2179
2240
|
states: { checked: { backgroundColor: 'var(--radio-accent)' } },
|
|
@@ -4394,6 +4455,45 @@ export const toggle: RecipeInput = {
|
|
|
4394
4455
|
},
|
|
4395
4456
|
},
|
|
4396
4457
|
defaultVariants: { color: 'primary', size: 'md' },
|
|
4458
|
+
// signalxjs/lynx#1204 — the lynx replacements for what this recipe's
|
|
4459
|
+
// shared sections cannot say there.
|
|
4460
|
+
targets: {
|
|
4461
|
+
lynx: {
|
|
4462
|
+
parts: {
|
|
4463
|
+
root: {
|
|
4464
|
+
// daisy's content-sized, never-squeezed btn (lynx#1165):
|
|
4465
|
+
// a lynx view has no inline formatting context, so the
|
|
4466
|
+
// toggle stretched to its column and a squeezed label
|
|
4467
|
+
// wrapped per character. The glyph + label sit in a row.
|
|
4468
|
+
// The hairline as longhands: a var-bearing `border`
|
|
4469
|
+
// shorthand expands after the cascade and would beat
|
|
4470
|
+
// any edge a later rule restates (lynx#1161/#1162).
|
|
4471
|
+
base: {
|
|
4472
|
+
...lynxBtnFit,
|
|
4473
|
+
flexDirection: 'row',
|
|
4474
|
+
border: '0 solid transparent',
|
|
4475
|
+
...lynxSides('border{}Width', 'var(--border)'),
|
|
4476
|
+
...lynxSides('border{}Color', 'var(--color-base-300)'),
|
|
4477
|
+
},
|
|
4478
|
+
states: {
|
|
4479
|
+
// No hover on a touch platform: the held toggle
|
|
4480
|
+
// takes the wash daisy's hover gives it. The shared
|
|
4481
|
+
// pressed rule adds the btn's 1px sink.
|
|
4482
|
+
pressed: { background: 'var(--color-base-300)' },
|
|
4483
|
+
on: lynxSides('border{}Color', 'var(--toggle-accent)'),
|
|
4484
|
+
// lynx's `outline` ignores the radius and has no
|
|
4485
|
+
// offset (lynx#1163): the ring as spread shadows.
|
|
4486
|
+
'focus-visible': lynxFocusRing('var(--toggle-accent)'),
|
|
4487
|
+
},
|
|
4488
|
+
selectors: {
|
|
4489
|
+
// A held on toggle keeps its fill (the web's
|
|
4490
|
+
// `[data-state=on]:hover` stays on the accent too).
|
|
4491
|
+
'&[data-state="on"][data-pressed]': { background: 'var(--toggle-accent)' },
|
|
4492
|
+
},
|
|
4493
|
+
},
|
|
4494
|
+
},
|
|
4495
|
+
},
|
|
4496
|
+
},
|
|
4397
4497
|
};
|
|
4398
4498
|
|
|
4399
4499
|
// daisy "join" of btns: one bordered capsule, hairline seams between items,
|
|
@@ -4505,6 +4605,65 @@ export const toggleGroup: RecipeInput = {
|
|
|
4505
4605
|
),
|
|
4506
4606
|
},
|
|
4507
4607
|
defaultVariants: { color: 'primary' },
|
|
4608
|
+
// signalxjs/lynx#1204 — the lynx replacements for what this recipe's
|
|
4609
|
+
// shared sections cannot say there.
|
|
4610
|
+
targets: {
|
|
4611
|
+
lynx: {
|
|
4612
|
+
parts: {
|
|
4613
|
+
root: {
|
|
4614
|
+
// Content-sized like the web's inline-flex capsule (a
|
|
4615
|
+
// lynx view stretches to its column otherwise), a row
|
|
4616
|
+
// unless vertical, and the frame as longhands so the
|
|
4617
|
+
// orientation rules below can drop one edge by
|
|
4618
|
+
// specificity (a var-bearing `border` shorthand would
|
|
4619
|
+
// expand over them, lynx#1161/#1162).
|
|
4620
|
+
base: {
|
|
4621
|
+
width: 'max-content',
|
|
4622
|
+
flexShrink: '0',
|
|
4623
|
+
flexDirection: 'row',
|
|
4624
|
+
border: '0 solid transparent',
|
|
4625
|
+
...lynxSides('border{}Width', 'var(--border)'),
|
|
4626
|
+
...lynxSides('border{}Color', 'var(--color-base-300)'),
|
|
4627
|
+
},
|
|
4628
|
+
selectors: {
|
|
4629
|
+
// The join seams: lynx has no sibling combinator, so
|
|
4630
|
+
// the web's `item + item` edge cannot be selected.
|
|
4631
|
+
// Every item draws its leading seam instead (below),
|
|
4632
|
+
// and the frame gives up that edge — the first item's
|
|
4633
|
+
// seam stands in for it, inside the frame's clip.
|
|
4634
|
+
'&[data-orientation="horizontal"]': { borderLeftWidth: '0' },
|
|
4635
|
+
'&[data-orientation="vertical"]': { borderTopWidth: '0' },
|
|
4636
|
+
},
|
|
4637
|
+
},
|
|
4638
|
+
item: {
|
|
4639
|
+
base: { flexShrink: '0', flexWrap: 'nowrap' },
|
|
4640
|
+
states: {
|
|
4641
|
+
// No hover on a touch platform: a held item takes the
|
|
4642
|
+
// wash daisy's hover gives it; an on item keeps its
|
|
4643
|
+
// fill (the selector below).
|
|
4644
|
+
pressed: { background: 'var(--color-base-300)' },
|
|
4645
|
+
// The frame clips its items, so the ring is drawn
|
|
4646
|
+
// inside the item (lynx's `outline` has no offset
|
|
4647
|
+
// and ignores the radius, lynx#1163).
|
|
4648
|
+
'focus-visible': lynxFocusRing('var(--toggle-group-accent)', { inset: true }),
|
|
4649
|
+
},
|
|
4650
|
+
selectors: {
|
|
4651
|
+
'&[data-state="on"][data-pressed]': { background: 'var(--toggle-group-accent)' },
|
|
4652
|
+
'&[data-orientation="horizontal"]': {
|
|
4653
|
+
borderLeftWidth: 'var(--border)',
|
|
4654
|
+
borderLeftStyle: 'solid',
|
|
4655
|
+
borderLeftColor: 'var(--color-base-300)',
|
|
4656
|
+
},
|
|
4657
|
+
'&[data-orientation="vertical"]': {
|
|
4658
|
+
borderTopWidth: 'var(--border)',
|
|
4659
|
+
borderTopStyle: 'solid',
|
|
4660
|
+
borderTopColor: 'var(--color-base-300)',
|
|
4661
|
+
},
|
|
4662
|
+
},
|
|
4663
|
+
},
|
|
4664
|
+
},
|
|
4665
|
+
},
|
|
4666
|
+
},
|
|
4508
4667
|
};
|
|
4509
4668
|
|
|
4510
4669
|
// daisy "join" of an input and two btns: one bordered capsule (the control),
|
|
@@ -4649,14 +4808,53 @@ export const numberInput: RecipeInput = {
|
|
|
4649
4808
|
xl: { control: { base: { height: fieldHeight('xl') } }, input: { base: { fontSize: 'var(--text-lg)', padding: 'var(--space-lg) var(--space-xl)' } } },
|
|
4650
4809
|
},
|
|
4651
4810
|
},
|
|
4652
|
-
//
|
|
4653
|
-
//
|
|
4654
|
-
//
|
|
4811
|
+
// Lynx restatements:
|
|
4812
|
+
// - the steppers' inline padding and their seams, physically: logical
|
|
4813
|
+
// spellings resolve on iOS but not on Android (measured,
|
|
4814
|
+
// signalxjs/lynx#1084);
|
|
4815
|
+
// - the steppers are views around a text glyph, with none of a
|
|
4816
|
+
// button's content centering;
|
|
4817
|
+
// - the native input takes no `inherit`: its ink is spelled out, and it
|
|
4818
|
+
// grows into any room a stretched control leaves between the steppers;
|
|
4819
|
+
// - the web root is inline-flex and hugs its content; lynx's flex column
|
|
4820
|
+
// stretches, so the children align to the start instead;
|
|
4821
|
+
// - the focus ring is `lynxFocusRing` (lynx's outline ignores the radius
|
|
4822
|
+
// and has no offset, signalxjs/lynx#1163). A shadow must not be
|
|
4823
|
+
// clipped by the box's own `overflow: hidden`, so the control stops
|
|
4824
|
+
// clipping and the steppers round their own outer corners instead.
|
|
4655
4825
|
targets: {
|
|
4656
4826
|
lynx: {
|
|
4657
4827
|
parts: {
|
|
4658
|
-
|
|
4659
|
-
|
|
4828
|
+
root: { base: { alignItems: 'flex-start' } },
|
|
4829
|
+
control: {
|
|
4830
|
+
base: { overflow: 'visible' },
|
|
4831
|
+
states: { 'focus-visible': lynxFocusRing('var(--number-input-accent)') },
|
|
4832
|
+
},
|
|
4833
|
+
input: { base: { color: 'var(--color-base-content)', flexGrow: '1' } },
|
|
4834
|
+
'increment-trigger': {
|
|
4835
|
+
base: {
|
|
4836
|
+
display: 'flex',
|
|
4837
|
+
alignItems: 'center',
|
|
4838
|
+
justifyContent: 'center',
|
|
4839
|
+
paddingLeft: 'var(--space-lg)',
|
|
4840
|
+
paddingRight: 'var(--space-lg)',
|
|
4841
|
+
borderLeft: 'var(--border) solid var(--color-base-300)',
|
|
4842
|
+
borderTopRightRadius: 'var(--radius-field)',
|
|
4843
|
+
borderBottomRightRadius: 'var(--radius-field)',
|
|
4844
|
+
},
|
|
4845
|
+
},
|
|
4846
|
+
'decrement-trigger': {
|
|
4847
|
+
base: {
|
|
4848
|
+
display: 'flex',
|
|
4849
|
+
alignItems: 'center',
|
|
4850
|
+
justifyContent: 'center',
|
|
4851
|
+
paddingLeft: 'var(--space-lg)',
|
|
4852
|
+
paddingRight: 'var(--space-lg)',
|
|
4853
|
+
borderRight: 'var(--border) solid var(--color-base-300)',
|
|
4854
|
+
borderTopLeftRadius: 'var(--radius-field)',
|
|
4855
|
+
borderBottomLeftRadius: 'var(--radius-field)',
|
|
4856
|
+
},
|
|
4857
|
+
},
|
|
4660
4858
|
},
|
|
4661
4859
|
},
|
|
4662
4860
|
},
|
|
@@ -5070,6 +5268,15 @@ const affixSize = (fontSize: string) => ({
|
|
|
5070
5268
|
'visibility-trigger': { base: { fontSize } },
|
|
5071
5269
|
});
|
|
5072
5270
|
|
|
5271
|
+
/**
|
|
5272
|
+
* A text field's placeholder ink on lynx (signalxjs/lynx#1205): the web's
|
|
5273
|
+
* `::placeholder` mix, for lynx's `-x-placeholder-color` property — the
|
|
5274
|
+
* emitter bakes the `color-mix()` to one literal per theme.
|
|
5275
|
+
*/
|
|
5276
|
+
const textFieldPlaceholder = 'color-mix(in oklab, var(--color-base-content) 60%, transparent)';
|
|
5277
|
+
/** The ghost field button's held look on lynx — the web's hover wash, on a press. */
|
|
5278
|
+
const fieldButtonHeld: CssProps = { color: 'var(--color-base-content)', background: 'var(--color-base-200)' };
|
|
5279
|
+
|
|
5073
5280
|
/**
|
|
5074
5281
|
* daisy "input" flavor: the shared field box with nothing in it but the text.
|
|
5075
5282
|
* Same `fieldControl` metrics as select's trigger, combobox's control and the
|
|
@@ -5191,6 +5398,53 @@ export const input: RecipeInput = {
|
|
|
5191
5398
|
xl: { control: { base: { height: fieldHeight('xl') } }, input: { base: { fontSize: 'var(--text-lg)', padding: 'var(--space-lg) var(--space-xl)' } }, ...affixSize('var(--text-lg)') },
|
|
5192
5399
|
},
|
|
5193
5400
|
},
|
|
5401
|
+
// lynx (signalxjs/lynx#1205). The field is a native text widget inside
|
|
5402
|
+
// a view `control`, so what the web gets from the cascade is restated:
|
|
5403
|
+
targets: {
|
|
5404
|
+
lynx: {
|
|
5405
|
+
parts: {
|
|
5406
|
+
// The web control is an `inline-flex` row; the emitter's
|
|
5407
|
+
// `flex` rewrite keeps no direction, so the row is explicit.
|
|
5408
|
+
// No `:hover` border on a touch platform — the ring below
|
|
5409
|
+
// (box-shadow spread, signalxjs/lynx#1163) is the focus cue,
|
|
5410
|
+
// in the root's accent like the web outline.
|
|
5411
|
+
control: {
|
|
5412
|
+
base: { flexDirection: 'row' },
|
|
5413
|
+
states: { 'focus-visible': lynxFocusRing('var(--input-accent)') },
|
|
5414
|
+
},
|
|
5415
|
+
// `color: inherit` never reaches a native text field, and
|
|
5416
|
+
// `::placeholder` does not exist: the ink is explicit and the
|
|
5417
|
+
// placeholder takes lynx's own `-x-placeholder-color`, the
|
|
5418
|
+
// web's 60% mix baked per theme.
|
|
5419
|
+
input: {
|
|
5420
|
+
base: {
|
|
5421
|
+
color: 'var(--color-base-content)',
|
|
5422
|
+
'-x-placeholder-color': textFieldPlaceholder,
|
|
5423
|
+
flexGrow: '1',
|
|
5424
|
+
flexShrink: '1',
|
|
5425
|
+
},
|
|
5426
|
+
},
|
|
5427
|
+
// The adornment's edge padding, physical: Android never
|
|
5428
|
+
// resolves the logical spellings (signalxjs/lynx#1084).
|
|
5429
|
+
adornment: {
|
|
5430
|
+
selectors: {
|
|
5431
|
+
'&[data-placement="start"]': { paddingLeft: 'var(--space-md)' },
|
|
5432
|
+
'&[data-placement="end"]': { paddingRight: 'var(--space-md)' },
|
|
5433
|
+
},
|
|
5434
|
+
},
|
|
5435
|
+
// Same for the ghost buttons' end margin; the web's `:hover`
|
|
5436
|
+
// wash answers a press instead.
|
|
5437
|
+
'clear-trigger': {
|
|
5438
|
+
base: { marginRight: 'var(--space-xs)' },
|
|
5439
|
+
states: { pressed: fieldButtonHeld },
|
|
5440
|
+
},
|
|
5441
|
+
'visibility-trigger': {
|
|
5442
|
+
base: { marginRight: 'var(--space-xs)' },
|
|
5443
|
+
states: { pressed: fieldButtonHeld },
|
|
5444
|
+
},
|
|
5445
|
+
},
|
|
5446
|
+
},
|
|
5447
|
+
},
|
|
5194
5448
|
};
|
|
5195
5449
|
|
|
5196
5450
|
/**
|
|
@@ -5259,6 +5513,22 @@ export const textarea: RecipeInput = {
|
|
|
5259
5513
|
xl: { textarea: { base: { fontSize: 'var(--text-lg)', minHeight: `calc(${fieldHeight('xl')} * 2)`, padding: 'var(--space-lg) var(--space-xl)' } } },
|
|
5260
5514
|
},
|
|
5261
5515
|
},
|
|
5516
|
+
// lynx (signalxjs/lynx#1205): lynx-zero renders the part as a view (the
|
|
5517
|
+
// box, whose state classes repaint) around the native field, which wears
|
|
5518
|
+
// the part's base class as its text face. So the ink and the placeholder
|
|
5519
|
+
// are explicit here — `color: inherit` and `::placeholder` never reach a
|
|
5520
|
+
// native widget — and the web's `:hover` border and outline ring become
|
|
5521
|
+
// the lynx focus ring in the root's accent (signalxjs/lynx#1163).
|
|
5522
|
+
targets: {
|
|
5523
|
+
lynx: {
|
|
5524
|
+
parts: {
|
|
5525
|
+
textarea: {
|
|
5526
|
+
base: { color: 'var(--color-base-content)', '-x-placeholder-color': textFieldPlaceholder },
|
|
5527
|
+
states: { 'focus-visible': lynxFocusRing('var(--textarea-accent)') },
|
|
5528
|
+
},
|
|
5529
|
+
},
|
|
5530
|
+
},
|
|
5531
|
+
},
|
|
5262
5532
|
};
|
|
5263
5533
|
|
|
5264
5534
|
// ── Content tier (#311) ───────────────────────────────────────────────────
|