@sigx/zero-daisyui 0.12.0 → 0.13.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/dist/css/components/combobox.css +2 -1
- package/dist/css/index.css +2 -1
- package/dist/lynx/components/checkbox.css +40 -9
- package/dist/lynx/components/combobox.css +2 -1
- package/dist/lynx/components/number-input.css +20 -0
- package/dist/lynx/components/radio-group.css +0 -1
- package/dist/lynx/components/textarea.css +9 -6
- package/dist/lynx/components/toast.css +0 -8
- package/dist/lynx/components/toggle-group.css +18 -5
- package/dist/lynx/index.css +89 -36
- package/dist/lynx/manifest.json +2 -2
- package/dist/lynx/tokens.css +0 -6
- package/dist/manifest.json +1 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/recipes.js +170 -27
- package/dist/recipes.js.map +1 -1
- package/dist/report.json +73 -1
- package/package.json +4 -4
- package/src/recipes.ts +174 -27
package/dist/report.json
CHANGED
|
@@ -10411,7 +10411,7 @@
|
|
|
10411
10411
|
{
|
|
10412
10412
|
"where": "lynx recipe for \"checkbox\"",
|
|
10413
10413
|
"what": "--checkbox-size",
|
|
10414
|
-
"detail": "calc-holding custom-property chain inlined: value substituted into
|
|
10414
|
+
"detail": "calc-holding custom-property chain inlined: value substituted into 4 consumer declaration(s) across 6 compound(s) and the definition dropped — lynx drops any declaration consuming var() of a property whose value holds calc() (measured, signalxjs/lynx#1075)",
|
|
10415
10415
|
"scope": "checkbox"
|
|
10416
10416
|
},
|
|
10417
10417
|
{
|
|
@@ -10848,6 +10848,36 @@
|
|
|
10848
10848
|
}
|
|
10849
10849
|
],
|
|
10850
10850
|
"dropped": [
|
|
10851
|
+
{
|
|
10852
|
+
"where": "lynx tokens, theme \"light\"",
|
|
10853
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10854
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10855
|
+
},
|
|
10856
|
+
{
|
|
10857
|
+
"where": "lynx tokens, theme \"light\"",
|
|
10858
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10859
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10860
|
+
},
|
|
10861
|
+
{
|
|
10862
|
+
"where": "lynx tokens, theme \"dark\"",
|
|
10863
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10864
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10865
|
+
},
|
|
10866
|
+
{
|
|
10867
|
+
"where": "lynx tokens, theme \"dim\"",
|
|
10868
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10869
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10870
|
+
},
|
|
10871
|
+
{
|
|
10872
|
+
"where": "lynx tokens, theme \"nord\"",
|
|
10873
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10874
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10875
|
+
},
|
|
10876
|
+
{
|
|
10877
|
+
"where": "lynx tokens, theme \"sunset\"",
|
|
10878
|
+
"what": "--fx-noise: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E\")",
|
|
10879
|
+
"detail": "an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative"
|
|
10880
|
+
},
|
|
10851
10881
|
{
|
|
10852
10882
|
"where": "lynx tokens",
|
|
10853
10883
|
"what": "prefers-reduced-motion duration collapse",
|
|
@@ -11525,12 +11555,36 @@
|
|
|
11525
11555
|
"detail": "padding-inline resolves on iOS but not on Android (measured, signalxjs/lynx#1084) — cross-platform-asymmetric, treated as unsupported; dropped, restate the geometry with a physical spelling (top/right/bottom/left, margin-*/padding-*) in the recipe's lynx target section",
|
|
11526
11556
|
"scope": "fieldset"
|
|
11527
11557
|
},
|
|
11558
|
+
{
|
|
11559
|
+
"where": "lynx recipe for \"checkbox\".\"control\"",
|
|
11560
|
+
"what": "backgroundImage: none, var(--fx-noise)",
|
|
11561
|
+
"detail": "reads --fx-noise, which the lynx tokens refuse — an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative",
|
|
11562
|
+
"scope": "checkbox"
|
|
11563
|
+
},
|
|
11528
11564
|
{
|
|
11529
11565
|
"where": "lynx recipe for \"checkbox\".\"indicator\"",
|
|
11530
11566
|
"what": "rotate: 45deg",
|
|
11531
11567
|
"detail": "the standalone rotate property resolves on iOS but not on Android (measured, signalxjs/lynx#1084) — cross-platform-asymmetric, treated as unsupported; dropped, spell the motion as a transform function (transform: rotate(...)) in the recipe's lynx target section",
|
|
11532
11568
|
"scope": "checkbox"
|
|
11533
11569
|
},
|
|
11570
|
+
{
|
|
11571
|
+
"where": "lynx recipe for \"checkbox\".\"indicator\"",
|
|
11572
|
+
"what": "clipPath: polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 70% 80%, 70% 100%)",
|
|
11573
|
+
"detail": "clip-path is not applied on lynx (measured on iOS, signalxjs/lynx#1216 — daisy's polygon-cut checkbox tick drew as the unclipped rotated square); dropped, draw the shape another way (borders, radii, transforms) in the recipe's lynx target section",
|
|
11574
|
+
"scope": "checkbox"
|
|
11575
|
+
},
|
|
11576
|
+
{
|
|
11577
|
+
"where": "lynx recipe for \"checkbox\".\"indicator\"",
|
|
11578
|
+
"what": "clipPath: polygon(20% 100%, 20% 80%, 50% 80%, 50% 0%, 70% 0%, 70% 100%)",
|
|
11579
|
+
"detail": "clip-path is not applied on lynx (measured on iOS, signalxjs/lynx#1216 — daisy's polygon-cut checkbox tick drew as the unclipped rotated square); dropped, draw the shape another way (borders, radii, transforms) in the recipe's lynx target section",
|
|
11580
|
+
"scope": "checkbox"
|
|
11581
|
+
},
|
|
11582
|
+
{
|
|
11583
|
+
"where": "lynx recipe for \"checkbox\".\"indicator\"",
|
|
11584
|
+
"what": "clipPath: polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 80% 80%, 80% 100%)",
|
|
11585
|
+
"detail": "clip-path is not applied on lynx (measured on iOS, signalxjs/lynx#1216 — daisy's polygon-cut checkbox tick drew as the unclipped rotated square); dropped, draw the shape another way (borders, radii, transforms) in the recipe's lynx target section",
|
|
11586
|
+
"scope": "checkbox"
|
|
11587
|
+
},
|
|
11534
11588
|
{
|
|
11535
11589
|
"where": "lynx recipe for \"checkbox\".\"indicator\"",
|
|
11536
11590
|
"what": "translate: 0 -35%",
|
|
@@ -11561,6 +11615,12 @@
|
|
|
11561
11615
|
"detail": "not expressible in the class grammar — dropped; supply a lynx replacement in the recipe target section",
|
|
11562
11616
|
"scope": "checkbox-group"
|
|
11563
11617
|
},
|
|
11618
|
+
{
|
|
11619
|
+
"where": "lynx recipe for \"radio-group\".\"item-indicator\"",
|
|
11620
|
+
"what": "backgroundImage: none, var(--fx-noise)",
|
|
11621
|
+
"detail": "reads --fx-noise, which the lynx tokens refuse — an SVG data-URI image fails to decode on iOS lynx — SDWebImage reports \"Downloaded image decode failed\" as a level-error image failure, the dev client's red error screen (measured, signalxjs/lynx#1215); dropped — the image is dropped with it, supply a raster or a lynx replacement in the recipe's lynx target section if it is not decorative",
|
|
11622
|
+
"scope": "radio-group"
|
|
11623
|
+
},
|
|
11564
11624
|
{
|
|
11565
11625
|
"where": "lynx recipe for \"progress\".\"range\"",
|
|
11566
11626
|
"what": "at[\"reduced-motion\"]",
|
|
@@ -11969,6 +12029,18 @@
|
|
|
11969
12029
|
"detail": "a color function over --border cannot bake — only the theme's --color-* vocabulary has a literal per theme, and a recipe-local property's value depends on which compound matched; dropped, supply a lynx replacement in the recipe target section",
|
|
11970
12030
|
"scope": "toast"
|
|
11971
12031
|
},
|
|
12032
|
+
{
|
|
12033
|
+
"where": "lynx recipe for \"toast\".\"indicator\"",
|
|
12034
|
+
"what": "clipPath: polygon(15.1% 41.3%, 1% 55%, 37.6% 92.8%, 99% 19.8%, 83.9% 7.2%, 36.6% 63.5%)",
|
|
12035
|
+
"detail": "clip-path is not applied on lynx (measured on iOS, signalxjs/lynx#1216 — daisy's polygon-cut checkbox tick drew as the unclipped rotated square); dropped, draw the shape another way (borders, radii, transforms) in the recipe's lynx target section",
|
|
12036
|
+
"scope": "toast"
|
|
12037
|
+
},
|
|
12038
|
+
{
|
|
12039
|
+
"where": "lynx recipe for \"toast\".\"indicator\"",
|
|
12040
|
+
"what": "clipPath: polygon(20% 8%, 50% 38%, 80% 8%, 92% 20%, 62% 50%, 92% 80%, 80% 92%, 50% 62%, 20% 92%, 8% 80%, 38% 50%, 8% 20%)",
|
|
12041
|
+
"detail": "clip-path is not applied on lynx (measured on iOS, signalxjs/lynx#1216 — daisy's polygon-cut checkbox tick drew as the unclipped rotated square); dropped, draw the shape another way (borders, radii, transforms) in the recipe's lynx target section",
|
|
12042
|
+
"scope": "toast"
|
|
12043
|
+
},
|
|
11972
12044
|
{
|
|
11973
12045
|
"where": "lynx recipe for \"toast\".\"indicator\"",
|
|
11974
12046
|
"what": "at[\"reduced-motion\"]",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigx/zero-daisyui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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.13.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.13.0",
|
|
70
|
+
"@sigx/zero-kit": "^0.13.0"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"access": "public"
|
package/src/recipes.ts
CHANGED
|
@@ -1825,6 +1825,13 @@ export const fieldset: RecipeInput = {
|
|
|
1825
1825
|
* horizontal bar and lifts it to the middle. All three verbatim from daisyUI
|
|
1826
1826
|
* 5.7.8's `.checkbox:before` / `:checked` / `:indeterminate`.
|
|
1827
1827
|
*/
|
|
1828
|
+
/**
|
|
1829
|
+
* The lynx tick's stroke: 20% of the checkbox's content box — the width of
|
|
1830
|
+
* daisy's polygon bars — as a length, since borders take no percentage.
|
|
1831
|
+
* The content box is the control less its padding and border on both sides.
|
|
1832
|
+
*/
|
|
1833
|
+
const CHECKBOX_LYNX_STROKE = 'calc((var(--checkbox-size) - var(--checkbox-pad) * 2 - var(--border) * 2) * 0.2)';
|
|
1834
|
+
|
|
1828
1835
|
const TICK_COLLAPSED = 'polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 70% 80%, 70% 100%)';
|
|
1829
1836
|
const TICK_DRAWN = 'polygon(20% 100%, 20% 80%, 50% 80%, 50% 0%, 70% 0%, 70% 100%)';
|
|
1830
1837
|
const DASH_DRAWN = 'polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 80% 80%, 80% 100%)';
|
|
@@ -2064,26 +2071,62 @@ export const checkbox: RecipeInput = {
|
|
|
2064
2071
|
},
|
|
2065
2072
|
},
|
|
2066
2073
|
indicator: {
|
|
2067
|
-
// The tick
|
|
2068
|
-
//
|
|
2069
|
-
//
|
|
2074
|
+
// The tick WITHOUT clip-path, which lynx does not apply
|
|
2075
|
+
// (measured on iOS, signalxjs/lynx#1216 — daisy's
|
|
2076
|
+
// polygon-cut box drew as a solid diamond; the emitter
|
|
2077
|
+
// now drops every clip-path). daisy's drawn polygon is an
|
|
2078
|
+
// L inside the content box: a bar at x 50–70% over the
|
|
2079
|
+
// full height and a foot at y 80–100% from x 20%, both
|
|
2080
|
+
// 20% of the box thick, rotated 45° about the box's
|
|
2081
|
+
// centre. That is exactly the classic two-border check:
|
|
2082
|
+
// a 50%-wide full-height box at x 20% with a right and a
|
|
2083
|
+
// bottom border 20% of the content box thick, turned
|
|
2084
|
+
// about the content box's centre (60% 50% of itself).
|
|
2070
2085
|
//
|
|
2071
|
-
// The
|
|
2072
|
-
//
|
|
2073
|
-
//
|
|
2074
|
-
//
|
|
2075
|
-
//
|
|
2076
|
-
// the
|
|
2086
|
+
// The ink: the control's `color:` names
|
|
2087
|
+
// `--checkbox-on-accent`, and `currentColor` was that ink
|
|
2088
|
+
// by inheritance (it never resolves on lynx,
|
|
2089
|
+
// signalxjs/lynx#1079) — spent directly on the borders.
|
|
2090
|
+
//
|
|
2091
|
+
// The motion is `transform`: the standalone `rotate` /
|
|
2092
|
+
// `translate` properties resolve on iOS but not on
|
|
2093
|
+
// Android (signalxjs/lynx#1084). No sheen shadow — on a
|
|
2094
|
+
// hollow box it would band the inside of the L.
|
|
2077
2095
|
base: {
|
|
2078
|
-
|
|
2096
|
+
boxSizing: 'border-box',
|
|
2097
|
+
width: '50%',
|
|
2098
|
+
height: '100%',
|
|
2099
|
+
marginLeft: '20%',
|
|
2100
|
+
backgroundColor: 'transparent',
|
|
2101
|
+
borderStyle: 'solid',
|
|
2102
|
+
borderColor: 'var(--checkbox-on-accent)',
|
|
2103
|
+
borderTopWidth: '0',
|
|
2104
|
+
borderLeftWidth: '0',
|
|
2105
|
+
borderRightWidth: CHECKBOX_LYNX_STROKE,
|
|
2106
|
+
borderBottomWidth: CHECKBOX_LYNX_STROKE,
|
|
2107
|
+
boxShadow: 'none',
|
|
2108
|
+
transformOrigin: '60% 50%',
|
|
2079
2109
|
transform: 'rotate(45deg)',
|
|
2080
|
-
transition: '
|
|
2081
|
-
+ 'opacity var(--duration-instant) var(--ease-standard) var(--duration-instant), '
|
|
2110
|
+
transition: 'opacity var(--duration-instant) var(--ease-standard) var(--duration-instant), '
|
|
2082
2111
|
+ 'transform var(--duration-slow) var(--ease-standard) var(--duration-instant)',
|
|
2083
2112
|
},
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2113
|
+
states: {
|
|
2114
|
+
// daisy's dash (signalxjs/lynx#1217): the same six
|
|
2115
|
+
// points un-rotated into a bar at x 20–80%, 20% of
|
|
2116
|
+
// the box tall, lifted to the middle. Here a filled,
|
|
2117
|
+
// borderless 60% × 20% box centred on the cross
|
|
2118
|
+
// axis — the unclipped full-height box had painted
|
|
2119
|
+
// the top half of the control.
|
|
2120
|
+
indeterminate: {
|
|
2121
|
+
width: '60%',
|
|
2122
|
+
height: '20%',
|
|
2123
|
+
alignSelf: 'center',
|
|
2124
|
+
borderRightWidth: '0',
|
|
2125
|
+
borderBottomWidth: '0',
|
|
2126
|
+
backgroundColor: 'var(--checkbox-on-accent)',
|
|
2127
|
+
transform: 'rotate(0deg)',
|
|
2128
|
+
},
|
|
2129
|
+
},
|
|
2087
2130
|
},
|
|
2088
2131
|
},
|
|
2089
2132
|
},
|
|
@@ -4149,6 +4192,11 @@ export const combobox: RecipeInput = {
|
|
|
4149
4192
|
flexWrap: 'wrap',
|
|
4150
4193
|
minWidth: '13rem',
|
|
4151
4194
|
...fieldControl,
|
|
4195
|
+
// The one field control that wraps: under `multiple` its tags
|
|
4196
|
+
// flow onto new rows, so the field step is a floor, not a cap —
|
|
4197
|
+
// a fixed height spills wrapped tags over the next field (#407).
|
|
4198
|
+
height: 'auto',
|
|
4199
|
+
minHeight: fieldHeight('md'),
|
|
4152
4200
|
transition: 'border-color var(--duration-fast) var(--ease-standard)',
|
|
4153
4201
|
},
|
|
4154
4202
|
states: {
|
|
@@ -4496,6 +4544,11 @@ export const toggle: RecipeInput = {
|
|
|
4496
4544
|
},
|
|
4497
4545
|
};
|
|
4498
4546
|
|
|
4547
|
+
/** A toggle-group end item's outer corner: the frame's radius inside its hairline. */
|
|
4548
|
+
const joinInnerRadius = 'calc(var(--radius-field) - var(--border))';
|
|
4549
|
+
/** A zero seam width that still holds var(), so it can beat the var-bearing seam on lynx. */
|
|
4550
|
+
const noSeam = 'calc(var(--border) * 0)';
|
|
4551
|
+
|
|
4499
4552
|
// daisy "join" of btns: one bordered capsule, hairline seams between items,
|
|
4500
4553
|
// the on item filled with the accent.
|
|
4501
4554
|
export const toggleGroup: RecipeInput = {
|
|
@@ -4625,15 +4678,13 @@ export const toggleGroup: RecipeInput = {
|
|
|
4625
4678
|
...lynxSides('border{}Width', 'var(--border)'),
|
|
4626
4679
|
...lynxSides('border{}Color', 'var(--color-base-300)'),
|
|
4627
4680
|
},
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
'&[data-orientation="vertical"]': { borderTopWidth: '0' },
|
|
4636
|
-
},
|
|
4681
|
+
// The frame keeps all four edges (signalxjs/lynx#1218).
|
|
4682
|
+
// It used to give up its leading edge to the first item's
|
|
4683
|
+
// seam and trust its own clip to round that item's
|
|
4684
|
+
// corners, but on iOS the frame's clip does not round the
|
|
4685
|
+
// leading corners: the first item painted square, and its
|
|
4686
|
+
// seam was lost with them. The `first`/`last` modifiers
|
|
4687
|
+
// below carry the join's ends instead.
|
|
4637
4688
|
},
|
|
4638
4689
|
item: {
|
|
4639
4690
|
base: { flexShrink: '0', flexWrap: 'nowrap' },
|
|
@@ -4649,6 +4700,10 @@ export const toggleGroup: RecipeInput = {
|
|
|
4649
4700
|
},
|
|
4650
4701
|
selectors: {
|
|
4651
4702
|
'&[data-state="on"][data-pressed]': { background: 'var(--toggle-group-accent)' },
|
|
4703
|
+
// The join seams: lynx has no sibling combinator, so
|
|
4704
|
+
// the web's `item + item` edge cannot be selected.
|
|
4705
|
+
// Every item draws its leading seam, and the `first`
|
|
4706
|
+
// modifier takes it off the item at the frame's edge.
|
|
4652
4707
|
'&[data-orientation="horizontal"]': {
|
|
4653
4708
|
borderLeftWidth: 'var(--border)',
|
|
4654
4709
|
borderLeftStyle: 'solid',
|
|
@@ -4662,6 +4717,40 @@ export const toggleGroup: RecipeInput = {
|
|
|
4662
4717
|
},
|
|
4663
4718
|
},
|
|
4664
4719
|
},
|
|
4720
|
+
// The ends of the join (signalxjs/lynx#1218). Lynx has no
|
|
4721
|
+
// `:first-child` or `:last-child`, so lynx-zero stamps the end
|
|
4722
|
+
// items itself, as `data-mod-first` / `data-mod-last` (the
|
|
4723
|
+
// `zx-m-first` / `zx-m-last` classes). They are a lynx-zero
|
|
4724
|
+
// rendering detail, not modifiers an author sets, so they are
|
|
4725
|
+
// not declared in the vocabulary and are styled from raw lynx
|
|
4726
|
+
// css. The end items round their own outer corners to the
|
|
4727
|
+
// frame's inner radius, so an on or held end item follows the
|
|
4728
|
+
// frame's corners without relying on its clip; `first` also
|
|
4729
|
+
// drops the leading seam, which would double the frame's edge.
|
|
4730
|
+
// That zero width is spelled through var() on purpose: a static
|
|
4731
|
+
// longhand loses to the var-bearing seam width whatever its
|
|
4732
|
+
// specificity (lynx expands var() declarations after the
|
|
4733
|
+
// cascade, signalxjs/lynx#1161).
|
|
4734
|
+
css: `
|
|
4735
|
+
.zx-toggle-group__item.zx-m-first.zx-o-horizontal {
|
|
4736
|
+
border-left-width: ${noSeam};
|
|
4737
|
+
border-top-left-radius: ${joinInnerRadius};
|
|
4738
|
+
border-bottom-left-radius: ${joinInnerRadius};
|
|
4739
|
+
}
|
|
4740
|
+
.zx-toggle-group__item.zx-m-first.zx-o-vertical {
|
|
4741
|
+
border-top-width: ${noSeam};
|
|
4742
|
+
border-top-left-radius: ${joinInnerRadius};
|
|
4743
|
+
border-top-right-radius: ${joinInnerRadius};
|
|
4744
|
+
}
|
|
4745
|
+
.zx-toggle-group__item.zx-m-last.zx-o-horizontal {
|
|
4746
|
+
border-top-right-radius: ${joinInnerRadius};
|
|
4747
|
+
border-bottom-right-radius: ${joinInnerRadius};
|
|
4748
|
+
}
|
|
4749
|
+
.zx-toggle-group__item.zx-m-last.zx-o-vertical {
|
|
4750
|
+
border-bottom-left-radius: ${joinInnerRadius};
|
|
4751
|
+
border-bottom-right-radius: ${joinInnerRadius};
|
|
4752
|
+
}
|
|
4753
|
+
`,
|
|
4665
4754
|
},
|
|
4666
4755
|
},
|
|
4667
4756
|
};
|
|
@@ -4830,7 +4919,19 @@ export const numberInput: RecipeInput = {
|
|
|
4830
4919
|
base: { overflow: 'visible' },
|
|
4831
4920
|
states: { 'focus-visible': lynxFocusRing('var(--number-input-accent)') },
|
|
4832
4921
|
},
|
|
4833
|
-
|
|
4922
|
+
// `::placeholder` does not exist on lynx, so the web's 60%
|
|
4923
|
+
// mix rides lynx's own `-x-placeholder-color` (baked per
|
|
4924
|
+
// theme) — without it the platform default reads dark on
|
|
4925
|
+
// dark (signalxjs/lynx#1222). Spelled out, not the
|
|
4926
|
+
// `textFieldPlaceholder` const: that one is declared further
|
|
4927
|
+
// down the module, after this literal is evaluated.
|
|
4928
|
+
input: {
|
|
4929
|
+
base: {
|
|
4930
|
+
color: 'var(--color-base-content)',
|
|
4931
|
+
'-x-placeholder-color': 'color-mix(in oklab, var(--color-base-content) 60%, transparent)',
|
|
4932
|
+
flexGrow: '1',
|
|
4933
|
+
},
|
|
4934
|
+
},
|
|
4834
4935
|
'increment-trigger': {
|
|
4835
4936
|
base: {
|
|
4836
4937
|
display: 'flex',
|
|
@@ -5447,6 +5548,10 @@ export const input: RecipeInput = {
|
|
|
5447
5548
|
},
|
|
5448
5549
|
};
|
|
5449
5550
|
|
|
5551
|
+
/** The lynx textarea floor: two field heights, as ONE calc() (signalxjs/lynx#1219). */
|
|
5552
|
+
const textareaFloor = (step: keyof typeof FIELD_STEPS): string =>
|
|
5553
|
+
`calc(var(--size-field) * ${FIELD_STEPS[step] * 2})`;
|
|
5554
|
+
|
|
5450
5555
|
/**
|
|
5451
5556
|
* daisy "textarea" flavor. The `fieldControl` box minus its `height`: the
|
|
5452
5557
|
* whole point of a textarea is that its height is the content's (and the
|
|
@@ -5519,12 +5624,54 @@ export const textarea: RecipeInput = {
|
|
|
5519
5624
|
// are explicit here — `color: inherit` and `::placeholder` never reach a
|
|
5520
5625
|
// native widget — and the web's `:hover` border and outline ring become
|
|
5521
5626
|
// the lynx focus ring in the root's accent (signalxjs/lynx#1163).
|
|
5627
|
+
//
|
|
5628
|
+
// The floor is one flat `calc(var(--size-field) * n)` per size
|
|
5629
|
+
// (signalxjs/lynx#1219): the shared `calc(fieldHeight * 2)` nests a
|
|
5630
|
+
// calc() in a calc(), and on device the box never took it — an empty
|
|
5631
|
+
// textarea sat one line tall.
|
|
5632
|
+
//
|
|
5633
|
+
// The focus ring is NOT `lynxFocusRing`'s two stacked outset shadows
|
|
5634
|
+
// (signalxjs/lynx#1220). Lynx iOS re-inserts a view's outset shadow
|
|
5635
|
+
// layers at a stale index whenever it re-lays the view out
|
|
5636
|
+
// (`LynxBackgroundManager.updateShadow` reads the sublayer count before
|
|
5637
|
+
// removing the old layers), which reverses their stacking: the 4px ring
|
|
5638
|
+
// lands on top of the 2px gap and paints one solid band. A fixed-height
|
|
5639
|
+
// box never re-lays out; this auto-height one does, as its native field
|
|
5640
|
+
// measures and grows. So the ring is spelled with one outset shadow and
|
|
5641
|
+
// one inset shadow, which paint disjoint areas and cannot swap: the ring
|
|
5642
|
+
// just outside the box, the box's own border repainted as the base-100
|
|
5643
|
+
// gap, and the hairline redrawn inside it by the inset spread, in the
|
|
5644
|
+
// edge colour (`--textarea-edge`, the error colour while invalid). The
|
|
5645
|
+
// gap is the border's width instead of the web's 2px.
|
|
5522
5646
|
targets: {
|
|
5523
5647
|
lynx: {
|
|
5524
5648
|
parts: {
|
|
5525
5649
|
textarea: {
|
|
5526
|
-
base: {
|
|
5527
|
-
|
|
5650
|
+
base: {
|
|
5651
|
+
color: 'var(--color-base-content)',
|
|
5652
|
+
'-x-placeholder-color': textFieldPlaceholder,
|
|
5653
|
+
'--textarea-edge': 'var(--color-base-300)',
|
|
5654
|
+
minHeight: textareaFloor('md'),
|
|
5655
|
+
},
|
|
5656
|
+
states: {
|
|
5657
|
+
invalid: { '--textarea-edge': 'var(--color-error)' },
|
|
5658
|
+
'focus-visible': {
|
|
5659
|
+
outline: 'none',
|
|
5660
|
+
borderColor: 'var(--color-base-100)',
|
|
5661
|
+
boxShadow: '0 0 0 2px var(--textarea-accent), '
|
|
5662
|
+
// Twice the border (1px in every shipped
|
|
5663
|
+
// theme): the inner half shows as the hairline.
|
|
5664
|
+
+ 'inset 0 0 0 2px var(--textarea-edge)',
|
|
5665
|
+
},
|
|
5666
|
+
},
|
|
5667
|
+
},
|
|
5668
|
+
},
|
|
5669
|
+
variants: {
|
|
5670
|
+
size: {
|
|
5671
|
+
xs: { textarea: { base: { minHeight: textareaFloor('xs') } } },
|
|
5672
|
+
sm: { textarea: { base: { minHeight: textareaFloor('sm') } } },
|
|
5673
|
+
lg: { textarea: { base: { minHeight: textareaFloor('lg') } } },
|
|
5674
|
+
xl: { textarea: { base: { minHeight: textareaFloor('xl') } } },
|
|
5528
5675
|
},
|
|
5529
5676
|
},
|
|
5530
5677
|
},
|