graphen 2.0.4 → 2.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphen",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Graphen is a small library, that keeps reusable blocks of UI and helps making application design consistent across multiple projects.",
5
5
  "main": "src/index.ts",
6
6
  "files": [
@@ -645,6 +645,72 @@ body.docs-body {
645
645
  .swatch-radius { width: 36px; height: 24px; background: var(--surface-2); border: 1px solid var(--border-strong); }
646
646
  }
647
647
 
648
+ .docs-bp-grid {
649
+ background: var(--bg-elev);
650
+ border: 1px solid var(--border);
651
+ border-radius: var(--radius-lg);
652
+ overflow: hidden;
653
+ }
654
+
655
+ .docs-bp-row {
656
+ display: grid;
657
+ grid-template-columns: 180px 120px 1fr;
658
+ gap: 16px;
659
+ align-items: center;
660
+ padding: 10px 18px;
661
+ border-top: 1px solid var(--border);
662
+
663
+ &:first-child { border-top: none; }
664
+
665
+ .mixin,
666
+ .range { font-family: var(--font-mono); font-size: 12.5px; }
667
+ .range { color: var(--text-muted); }
668
+ .vars { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
669
+ }
670
+
671
+ .docs-bp-demo {
672
+ display: flex;
673
+ flex-wrap: wrap;
674
+ justify-content: center;
675
+ gap: 12px;
676
+
677
+ .pill {
678
+ display: flex;
679
+ flex-direction: column;
680
+ align-items: center;
681
+ gap: 2px;
682
+ min-width: 128px;
683
+ padding: 10px 18px;
684
+ border: 1px dashed var(--border-strong);
685
+ border-radius: var(--radius);
686
+ opacity: 0.35;
687
+ transition: opacity 0.15s, border-color 0.15s, background 0.15s;
688
+
689
+ .nm { font-family: var(--font-mono); font-size: 12.5px; color: var(--text); }
690
+ .rg { font-family: var(--font-mono); font-size: 11px; color: var(--text-subtle); }
691
+ }
692
+ }
693
+
694
+ /* The live part of the Responsiveness demo — powered by the
695
+ library's own gx-* mixins, not by docs-local media queries. */
696
+ @mixin docs-bp-pill-active {
697
+ background: var(--accent-soft);
698
+ border: 1px solid var(--accent);
699
+ opacity: 1;
700
+ }
701
+
702
+ @include gx-phone {
703
+ .docs-bp-demo .pill--phone { @include docs-bp-pill-active; }
704
+ }
705
+
706
+ @include gx-tablet {
707
+ .docs-bp-demo .pill--tablet { @include docs-bp-pill-active; }
708
+ }
709
+
710
+ @include gx-desktop {
711
+ .docs-bp-demo .pill--desktop { @include docs-bp-pill-active; }
712
+ }
713
+
648
714
  .docs-comp-index {
649
715
  display: grid;
650
716
  grid-template-columns: repeat(4, 1fr);
package/src/example.tsx CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  SegmentedControl,
16
16
  Separator,
17
17
  Stat,
18
+ Switch,
18
19
  constants,
19
20
  } from "./index";
20
21
 
@@ -104,6 +105,16 @@ const SPACING = [
104
105
  ["$gb-sp-16", "64 px", "4rem", 64],
105
106
  ] as const;
106
107
 
108
+ const BREAKPOINTS = [
109
+ ["@include gx-phone", "< 768 px", "up to $g-tablet-width − 1px"],
110
+ [
111
+ "@include gx-tablet",
112
+ "768 – 1023 px",
113
+ "$g-tablet-width … $g-desktop-width − 1px",
114
+ ],
115
+ ["@include gx-desktop", "≥ 1024 px", "$g-desktop-width and up"],
116
+ ] as const;
117
+
107
118
  const RADIUS = [
108
119
  ["$gb-r-sm", "4 px", 4],
109
120
  ["$gb-r", "6 px", 6],
@@ -166,6 +177,7 @@ const NAV = [
166
177
  { id: "typography", label: "Typography" },
167
178
  { id: "spacing", label: "Spacing & radius" },
168
179
  { id: "iconography", label: "Iconography", count: "14" },
180
+ { id: "responsiveness", label: "Responsiveness" },
169
181
  ],
170
182
  },
171
183
  {
@@ -185,6 +197,7 @@ const NAV = [
185
197
  { id: "segmented-control", label: "Segmented control" },
186
198
  { id: "stat", label: "Stat" },
187
199
  { id: "cover-empty", label: "Cover empty" },
200
+ { id: "switch", label: "Switch" },
188
201
  ],
189
202
  },
190
203
  ];
@@ -195,6 +208,7 @@ const TOC = [
195
208
  ["typography", "Typography"],
196
209
  ["spacing", "Spacing & radius"],
197
210
  ["iconography", "Iconography"],
211
+ ["responsiveness", "Responsiveness"],
198
212
  ["logo", "Logo"],
199
213
  ["button", "Button"],
200
214
  ["link", "Link"],
@@ -209,6 +223,7 @@ const TOC = [
209
223
  ["segmented-control", "Segmented control"],
210
224
  ["stat", "Stat"],
211
225
  ["cover-empty", "Cover empty"],
226
+ ["switch", "Switch"],
212
227
  ] as const;
213
228
 
214
229
  type IconProps = {
@@ -713,6 +728,60 @@ function App() {
713
728
  </div>
714
729
  </section>
715
730
 
731
+ <section className="docs-section" id="responsiveness">
732
+ <div className="docs-section-eyebrow">Foundations / 05</div>
733
+ <h2 className="docs-section-title">Responsiveness</h2>
734
+ <p className="docs-section-desc">
735
+ Breakpoints are exposed as Sass variables and wrapped by three
736
+ mixins — <code>gx-phone</code>, <code>gx-tablet</code> and{" "}
737
+ <code>gx-desktop</code>. Each mixin scopes its block to exactly
738
+ one range, so the three never overlap. The demo below is styled
739
+ with the real mixins — resize the window to see the active range
740
+ light up.
741
+ </p>
742
+ <div className="docs-bp-grid" role="table" aria-label="Breakpoints">
743
+ {BREAKPOINTS.map(([mixin, range, vars]) => (
744
+ <div className="docs-bp-row" key={mixin}>
745
+ <span className="mixin">{mixin}</span>
746
+ <span className="range">{range}</span>
747
+ <span className="vars">{vars}</span>
748
+ </div>
749
+ ))}
750
+ </div>
751
+ <div className="docs-spacer-y" />
752
+ <Demo
753
+ stageClass="center"
754
+ code={`.docs-bp-demo .pill { opacity: 0.35; }
755
+
756
+ @include gx-phone {
757
+ .docs-bp-demo .pill--phone { opacity: 1; }
758
+ }
759
+
760
+ @include gx-tablet {
761
+ .docs-bp-demo .pill--tablet { opacity: 1; }
762
+ }
763
+
764
+ @include gx-desktop {
765
+ .docs-bp-demo .pill--desktop { opacity: 1; }
766
+ }`}
767
+ >
768
+ <div className="docs-bp-demo">
769
+ <div className="pill pill--phone">
770
+ <span className="nm">gx-phone</span>
771
+ <span className="rg">&lt; 768 px</span>
772
+ </div>
773
+ <div className="pill pill--tablet">
774
+ <span className="nm">gx-tablet</span>
775
+ <span className="rg">768 – 1023 px</span>
776
+ </div>
777
+ <div className="pill pill--desktop">
778
+ <span className="nm">gx-desktop</span>
779
+ <span className="rg">≥ 1024 px</span>
780
+ </div>
781
+ </div>
782
+ </Demo>
783
+ </section>
784
+
716
785
  <section className="docs-section" id="logo">
717
786
  <div className="docs-section-eyebrow">Components / 01</div>
718
787
  <h2 className="docs-section-title">Logo</h2>
@@ -1144,6 +1213,30 @@ function App() {
1144
1213
  </Demo>
1145
1214
  </section>
1146
1215
 
1216
+ <section className="docs-section" id="switch">
1217
+ <div className="docs-section-eyebrow">Components / 15</div>
1218
+ <h2 className="docs-section-title">Switch</h2>
1219
+ <p className="docs-section-desc">
1220
+ A toggle for a single on / off setting that takes effect
1221
+ immediately. The <code>type</code> prop colors the active state to
1222
+ match the semantic palette.
1223
+ </p>
1224
+ <Demo
1225
+ stageClass="center"
1226
+ code={`<Switch onChange={(isSwitched) => console.log(isSwitched)} />
1227
+ <Switch isSwitched />
1228
+ <Switch isSwitched type="success" />
1229
+ <Switch isSwitched type="info" />
1230
+ <Switch isSwitched type="danger" />`}
1231
+ >
1232
+ <Switch />
1233
+ <Switch isSwitched />
1234
+ <Switch isSwitched type="success" />
1235
+ <Switch isSwitched type="info" />
1236
+ <Switch isSwitched type="danger" />
1237
+ </Demo>
1238
+ </section>
1239
+
1147
1240
  <footer className="docs-footer">
1148
1241
  <div>graphen · {VERSION} · MIT</div>
1149
1242
  <div>Built by the CODA_ team</div>