@quilltap/theme-storybook 1.0.66 → 1.0.68
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/CHANGELOG.md +8 -0
- package/dist/{chunk-PCPCAOQ7.mjs → chunk-IAVNW2EO.mjs} +22 -0
- package/dist/index.css +33 -0
- package/dist/index.js +22 -0
- package/dist/index.mjs +1 -1
- package/dist/stories/index.js +22 -0
- package/dist/stories/index.mjs +1 -1
- package/package.json +1 -1
- package/src/css/qt-components.css +66 -0
- package/src/stories/components/Inputs.tsx +23 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@quilltap/theme-storybook` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.67] - 2026-08-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `.qt-range` and its two tokens (`--qt-range-accent`, `--qt-range-focus-ring`), mirroring the app's new slider class, plus a "Range Sliders" section in the `Inputs` story so a theme can be previewed against an enabled and a disabled slider.
|
|
9
|
+
|
|
10
|
+
### Notes
|
|
11
|
+
- Sliders stay natively rendered. `accent-color` is what paints the filled portion of the track *and* the thumb, so it is the whole default theming story; the class sets no disabled opacity, because browsers already drop the accent on a disabled range and app call sites nest sliders inside dimmed wrappers. A theme wanting a bespoke track can override `.qt-range` with `appearance: none`, at the cost of the filled bar in Chrome and Safari.
|
|
12
|
+
|
|
5
13
|
## [1.0.63] - 2026-08-25
|
|
6
14
|
|
|
7
15
|
### Added
|
|
@@ -848,6 +848,28 @@ var Inputs = () => {
|
|
|
848
848
|
] })
|
|
849
849
|
] })
|
|
850
850
|
] }),
|
|
851
|
+
/* @__PURE__ */ jsxs7("section", { style: { marginBottom: "2rem" }, children: [
|
|
852
|
+
/* @__PURE__ */ jsx7("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Range Sliders" }),
|
|
853
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexDirection: "column", gap: "1rem", maxWidth: "24rem" }, children: [
|
|
854
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
855
|
+
/* @__PURE__ */ jsx7("label", { className: "qt-label", htmlFor: "range1", children: "Temperature" }),
|
|
856
|
+
/* @__PURE__ */ jsx7("input", { type: "range", id: "range1", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 65 })
|
|
857
|
+
] }),
|
|
858
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
859
|
+
/* @__PURE__ */ jsx7("label", { className: "qt-label", htmlFor: "range2", style: { color: "var(--color-muted-foreground)" }, children: "Disabled slider" }),
|
|
860
|
+
/* @__PURE__ */ jsx7("input", { type: "range", id: "range2", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 35, disabled: true })
|
|
861
|
+
] })
|
|
862
|
+
] }),
|
|
863
|
+
/* @__PURE__ */ jsxs7("p", { style: { fontSize: "0.75rem", color: "var(--color-muted-foreground)", marginTop: "0.75rem", maxWidth: "32rem" }, children: [
|
|
864
|
+
"Sliders render natively; ",
|
|
865
|
+
/* @__PURE__ */ jsx7("code", { children: "--qt-range-accent" }),
|
|
866
|
+
" colours both the filled portion of the track and the thumb. Overriding ",
|
|
867
|
+
/* @__PURE__ */ jsx7("code", { children: ".qt-range" }),
|
|
868
|
+
" with",
|
|
869
|
+
/* @__PURE__ */ jsx7("code", { children: " appearance: none" }),
|
|
870
|
+
" gives a theme full control of the track, but drops the filled bar in Chrome and Safari."
|
|
871
|
+
] })
|
|
872
|
+
] }),
|
|
851
873
|
/* @__PURE__ */ jsxs7("section", { style: { marginBottom: "2rem" }, children: [
|
|
852
874
|
/* @__PURE__ */ jsx7("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Links" }),
|
|
853
875
|
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
package/dist/index.css
CHANGED
|
@@ -230,6 +230,8 @@ body {
|
|
|
230
230
|
--qt-radio-border: var(--color-border);
|
|
231
231
|
--qt-radio-accent: var(--color-primary);
|
|
232
232
|
--qt-radio-focus-ring: var(--color-ring);
|
|
233
|
+
--qt-range-accent: var(--color-primary);
|
|
234
|
+
--qt-range-focus-ring: var(--color-ring);
|
|
233
235
|
--qt-navbar-height: 3.5rem;
|
|
234
236
|
--qt-navbar-bg: var(--color-background);
|
|
235
237
|
--qt-navbar-border: var(--color-border);
|
|
@@ -852,6 +854,17 @@ body {
|
|
|
852
854
|
outline: none;
|
|
853
855
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--qt-radio-focus-ring) 35%, transparent);
|
|
854
856
|
}
|
|
857
|
+
.qt-range {
|
|
858
|
+
cursor: pointer;
|
|
859
|
+
accent-color: var(--qt-range-accent);
|
|
860
|
+
}
|
|
861
|
+
.qt-range:focus-visible {
|
|
862
|
+
outline: none;
|
|
863
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--qt-range-focus-ring) 35%, transparent);
|
|
864
|
+
}
|
|
865
|
+
.qt-range:disabled {
|
|
866
|
+
cursor: not-allowed;
|
|
867
|
+
}
|
|
855
868
|
.qt-badge {
|
|
856
869
|
display: inline-flex;
|
|
857
870
|
align-items: center;
|
|
@@ -933,6 +946,26 @@ body {
|
|
|
933
946
|
color: var(--qt-status-info-fg);
|
|
934
947
|
border: 1px solid var(--qt-status-info-border);
|
|
935
948
|
}
|
|
949
|
+
.qt-danger-badge {
|
|
950
|
+
--qt-concierge-badge-color: var(--color-destructive, #dc2626);
|
|
951
|
+
display: inline-flex;
|
|
952
|
+
align-items: center;
|
|
953
|
+
gap: 0.25rem;
|
|
954
|
+
padding: 0.125rem 0.375rem;
|
|
955
|
+
border-radius: 0.25rem;
|
|
956
|
+
font-size: 0.75rem;
|
|
957
|
+
line-height: 1rem;
|
|
958
|
+
font-weight: 500;
|
|
959
|
+
background: color-mix(in srgb, var(--qt-concierge-badge-color) 15%, transparent);
|
|
960
|
+
color: var(--qt-concierge-badge-color);
|
|
961
|
+
border: 1px solid color-mix(in srgb, var(--qt-concierge-badge-color) 40%, transparent);
|
|
962
|
+
}
|
|
963
|
+
.qt-danger-badge-muted {
|
|
964
|
+
--qt-concierge-badge-color: var(--color-muted-foreground, #6b7280);
|
|
965
|
+
}
|
|
966
|
+
.qt-danger-badge-info {
|
|
967
|
+
--qt-concierge-badge-color: var(--color-info, #2563eb);
|
|
968
|
+
}
|
|
936
969
|
.qt-badge-wardrobe-top,
|
|
937
970
|
.qt-badge-wardrobe-bottom,
|
|
938
971
|
.qt-badge-wardrobe-footwear,
|
package/dist/index.js
CHANGED
|
@@ -958,6 +958,28 @@ var Inputs = () => {
|
|
|
958
958
|
] })
|
|
959
959
|
] })
|
|
960
960
|
] }),
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
962
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Range Sliders" }),
|
|
963
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem", maxWidth: "24rem" }, children: [
|
|
964
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
965
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "qt-label", htmlFor: "range1", children: "Temperature" }),
|
|
966
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "range", id: "range1", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 65 })
|
|
967
|
+
] }),
|
|
968
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
969
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "qt-label", htmlFor: "range2", style: { color: "var(--color-muted-foreground)" }, children: "Disabled slider" }),
|
|
970
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "range", id: "range2", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 35, disabled: true })
|
|
971
|
+
] })
|
|
972
|
+
] }),
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { style: { fontSize: "0.75rem", color: "var(--color-muted-foreground)", marginTop: "0.75rem", maxWidth: "32rem" }, children: [
|
|
974
|
+
"Sliders render natively; ",
|
|
975
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "--qt-range-accent" }),
|
|
976
|
+
" colours both the filled portion of the track and the thumb. Overriding ",
|
|
977
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: ".qt-range" }),
|
|
978
|
+
" with",
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: " appearance: none" }),
|
|
980
|
+
" gives a theme full control of the track, but drops the filled bar in Chrome and Safari."
|
|
981
|
+
] })
|
|
982
|
+
] }),
|
|
961
983
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
962
984
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Links" }),
|
|
963
985
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
package/dist/index.mjs
CHANGED
package/dist/stories/index.js
CHANGED
|
@@ -895,6 +895,28 @@ var Inputs = () => {
|
|
|
895
895
|
] })
|
|
896
896
|
] })
|
|
897
897
|
] }),
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
899
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Range Sliders" }),
|
|
900
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem", maxWidth: "24rem" }, children: [
|
|
901
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "qt-label", htmlFor: "range1", children: "Temperature" }),
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "range", id: "range1", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 65 })
|
|
904
|
+
] }),
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "qt-label", htmlFor: "range2", style: { color: "var(--color-muted-foreground)" }, children: "Disabled slider" }),
|
|
907
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "range", id: "range2", className: "qt-range", style: { width: "100%" }, min: 0, max: 100, defaultValue: 35, disabled: true })
|
|
908
|
+
] })
|
|
909
|
+
] }),
|
|
910
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: { fontSize: "0.75rem", color: "var(--color-muted-foreground)", marginTop: "0.75rem", maxWidth: "32rem" }, children: [
|
|
911
|
+
"Sliders render natively; ",
|
|
912
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "--qt-range-accent" }),
|
|
913
|
+
" colours both the filled portion of the track and the thumb. Overriding ",
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: ".qt-range" }),
|
|
915
|
+
" with",
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: " appearance: none" }),
|
|
917
|
+
" gives a theme full control of the track, but drops the filled bar in Chrome and Safari."
|
|
918
|
+
] })
|
|
919
|
+
] }),
|
|
898
920
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
899
921
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: { fontSize: "1.125rem", fontWeight: 700, marginBottom: "1rem", borderBottom: "1px solid var(--color-border)", paddingBottom: "0.5rem" }, children: "Links" }),
|
|
900
922
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
package/dist/stories/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -83,6 +83,12 @@
|
|
|
83
83
|
--qt-radio-accent: var(--color-primary);
|
|
84
84
|
--qt-radio-focus-ring: var(--color-ring);
|
|
85
85
|
|
|
86
|
+
/* Range slider variables. Sliders stay natively rendered: accent-color paints
|
|
87
|
+
the filled track and the thumb, which `appearance: none` would discard in
|
|
88
|
+
Chrome and Safari. */
|
|
89
|
+
--qt-range-accent: var(--color-primary);
|
|
90
|
+
--qt-range-focus-ring: var(--color-ring);
|
|
91
|
+
|
|
86
92
|
/* Navbar variables */
|
|
87
93
|
--qt-navbar-height: 3.5rem;
|
|
88
94
|
--qt-navbar-bg: var(--color-background);
|
|
@@ -873,6 +879,31 @@
|
|
|
873
879
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--qt-radio-focus-ring) 35%, transparent);
|
|
874
880
|
}
|
|
875
881
|
|
|
882
|
+
/* ==========================================================================
|
|
883
|
+
RANGE (SLIDER) COMPONENT
|
|
884
|
+
Natively rendered on purpose — accent-color paints the filled portion of the
|
|
885
|
+
track and the thumb. Do not reimplement with appearance:none plus custom
|
|
886
|
+
::-webkit-slider-thumb / ::-moz-range-thumb rules: that discards the filled
|
|
887
|
+
bar in Chrome and Safari. Call sites own width/layout.
|
|
888
|
+
========================================================================== */
|
|
889
|
+
|
|
890
|
+
.qt-range {
|
|
891
|
+
cursor: pointer;
|
|
892
|
+
accent-color: var(--qt-range-accent);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.qt-range:focus-visible {
|
|
896
|
+
outline: none;
|
|
897
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--qt-range-focus-ring) 35%, transparent);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* No disabled opacity on purpose: browsers already drop the accent on a
|
|
901
|
+
disabled range, and app call sites nest these inside dimmed wrappers where a
|
|
902
|
+
second 50% would compound to 25%. */
|
|
903
|
+
.qt-range:disabled {
|
|
904
|
+
cursor: not-allowed;
|
|
905
|
+
}
|
|
906
|
+
|
|
876
907
|
/* ==========================================================================
|
|
877
908
|
BADGE COMPONENTS
|
|
878
909
|
========================================================================== */
|
|
@@ -1001,6 +1032,41 @@
|
|
|
1001
1032
|
border: 1px solid var(--qt-status-info-border);
|
|
1002
1033
|
}
|
|
1003
1034
|
|
|
1035
|
+
/* ==========================================================================
|
|
1036
|
+
CONCIERGE BADGE (Salon breadcrumb header)
|
|
1037
|
+
========================================================================== */
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Concierge badge for the Salon breadcrumb header. Parameterized over one
|
|
1041
|
+
* CSS var so the four-state family is a recolor, not four rules: the base
|
|
1042
|
+
* is the red Flagged pill; the modifiers below recolor it for the two
|
|
1043
|
+
* operator states (Monitored renders no badge at all).
|
|
1044
|
+
*/
|
|
1045
|
+
.qt-danger-badge {
|
|
1046
|
+
--qt-concierge-badge-color: var(--color-destructive, #dc2626);
|
|
1047
|
+
display: inline-flex;
|
|
1048
|
+
align-items: center;
|
|
1049
|
+
gap: 0.25rem;
|
|
1050
|
+
padding: 0.125rem 0.375rem;
|
|
1051
|
+
border-radius: 0.25rem;
|
|
1052
|
+
font-size: 0.75rem;
|
|
1053
|
+
line-height: 1rem;
|
|
1054
|
+
font-weight: 500;
|
|
1055
|
+
background: color-mix(in srgb, var(--qt-concierge-badge-color) 15%, transparent);
|
|
1056
|
+
color: var(--qt-concierge-badge-color);
|
|
1057
|
+
border: 1px solid color-mix(in srgb, var(--qt-concierge-badge-color) 40%, transparent);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/* Vouched Safe — no colour: the Concierge isn't in the room. */
|
|
1061
|
+
.qt-danger-badge-muted {
|
|
1062
|
+
--qt-concierge-badge-color: var(--color-muted-foreground, #6b7280);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/* Uncensored — the eye you closed yourself. */
|
|
1066
|
+
.qt-danger-badge-info {
|
|
1067
|
+
--qt-concierge-badge-color: var(--color-info, #2563eb);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1004
1070
|
/* ==========================================================================
|
|
1005
1071
|
WARDROBE SLOT BADGES
|
|
1006
1072
|
========================================================================== */
|
|
@@ -102,6 +102,29 @@ export const Inputs: React.FC = () => {
|
|
|
102
102
|
</div>
|
|
103
103
|
</section>
|
|
104
104
|
|
|
105
|
+
{/* Range sliders */}
|
|
106
|
+
<section style={{ marginBottom: '2rem' }}>
|
|
107
|
+
<h3 style={{ fontSize: '1.125rem', fontWeight: 700, marginBottom: '1rem', borderBottom: '1px solid var(--color-border)', paddingBottom: '0.5rem' }}>
|
|
108
|
+
Range Sliders
|
|
109
|
+
</h3>
|
|
110
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: '24rem' }}>
|
|
111
|
+
<div>
|
|
112
|
+
<label className="qt-label" htmlFor="range1">Temperature</label>
|
|
113
|
+
<input type="range" id="range1" className="qt-range" style={{ width: '100%' }} min={0} max={100} defaultValue={65} />
|
|
114
|
+
</div>
|
|
115
|
+
<div>
|
|
116
|
+
<label className="qt-label" htmlFor="range2" style={{ color: 'var(--color-muted-foreground)' }}>Disabled slider</label>
|
|
117
|
+
<input type="range" id="range2" className="qt-range" style={{ width: '100%' }} min={0} max={100} defaultValue={35} disabled />
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<p style={{ fontSize: '0.75rem', color: 'var(--color-muted-foreground)', marginTop: '0.75rem', maxWidth: '32rem' }}>
|
|
121
|
+
Sliders render natively; <code>--qt-range-accent</code> colours both the filled
|
|
122
|
+
portion of the track and the thumb. Overriding <code>.qt-range</code> with
|
|
123
|
+
<code> appearance: none</code> gives a theme full control of the track, but drops
|
|
124
|
+
the filled bar in Chrome and Safari.
|
|
125
|
+
</p>
|
|
126
|
+
</section>
|
|
127
|
+
|
|
105
128
|
{/* Links */}
|
|
106
129
|
<section style={{ marginBottom: '2rem' }}>
|
|
107
130
|
<h3 style={{ fontSize: '1.125rem', fontWeight: 700, marginBottom: '1rem', borderBottom: '1px solid var(--color-border)', paddingBottom: '0.5rem' }}>
|