graphen 2.0.7 → 2.0.9

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/src/example.tsx CHANGED
@@ -2,20 +2,35 @@
2
2
  import React, { useEffect, useMemo, useState } from "react";
3
3
  import { render } from "react-dom";
4
4
  import {
5
+ Accordion,
5
6
  Badge,
6
7
  Button,
7
8
  Card,
8
9
  CoverEmpty,
9
10
  Dialog,
10
11
  Dropdown,
12
+ Flex,
13
+ FlexItem,
11
14
  Icons,
12
15
  Input,
16
+ Joystick,
13
17
  Link,
18
+ Loader,
14
19
  Logo,
20
+ Navigation,
21
+ NavigationOption,
22
+ Panel,
23
+ PanelContent,
24
+ PanelFooter,
25
+ PanelTitle,
26
+ Scroller,
15
27
  SegmentedControl,
16
28
  Separator,
29
+ Skeleton,
17
30
  Stat,
18
31
  Switch,
32
+ Tooltip,
33
+ Validation,
19
34
  constants,
20
35
  } from "./index";
21
36
 
@@ -198,6 +213,19 @@ const NAV = [
198
213
  { id: "stat", label: "Stat" },
199
214
  { id: "cover-empty", label: "Cover empty" },
200
215
  { id: "switch", label: "Switch" },
216
+ { id: "panel", label: "Panel" },
217
+ { id: "accordion", label: "Accordion" },
218
+ { id: "flex", label: "Flex" },
219
+ { id: "loader", label: "Loader" },
220
+ { id: "skeleton", label: "Skeleton" },
221
+ { id: "tooltip", label: "Tooltip" },
222
+ { id: "validation", label: "Validation" },
223
+ { id: "alert", label: "Alert" },
224
+ { id: "list", label: "List" },
225
+ { id: "textarea", label: "Textarea" },
226
+ { id: "led", label: "LED" },
227
+ { id: "joystick", label: "Joystick" },
228
+ { id: "scroller", label: "Scroller" },
201
229
  ],
202
230
  },
203
231
  ];
@@ -224,6 +252,19 @@ const TOC = [
224
252
  ["stat", "Stat"],
225
253
  ["cover-empty", "Cover empty"],
226
254
  ["switch", "Switch"],
255
+ ["panel", "Panel"],
256
+ ["accordion", "Accordion"],
257
+ ["flex", "Flex"],
258
+ ["loader", "Loader"],
259
+ ["skeleton", "Skeleton"],
260
+ ["tooltip", "Tooltip"],
261
+ ["validation", "Validation"],
262
+ ["alert", "Alert"],
263
+ ["list", "List"],
264
+ ["textarea", "Textarea"],
265
+ ["led", "LED"],
266
+ ["joystick", "Joystick"],
267
+ ["scroller", "Scroller"],
227
268
  ] as const;
228
269
 
229
270
  type IconProps = {
@@ -277,6 +318,39 @@ function CopyButton({
277
318
  );
278
319
  }
279
320
 
321
+ function JoystickDemo() {
322
+ const [position, setPosition] = useState({ left: 0, top: 0 });
323
+ return (
324
+ <>
325
+ <Joystick
326
+ isEnabled
327
+ onPositionChange={(left, top) =>
328
+ setPosition({ left: Math.round(left), top: Math.round(top) })
329
+ }
330
+ />
331
+ <span className="docs-demo-value">
332
+ left: {position.left} / top: {position.top}
333
+ </span>
334
+ </>
335
+ );
336
+ }
337
+
338
+ function ScrollerDemo() {
339
+ const [scrollValue, setScrollValue] = useState(0);
340
+ return (
341
+ <>
342
+ <div className="docs-scroller-track">
343
+ <Scroller
344
+ min={0}
345
+ max={100}
346
+ onScrollChange={(value) => setScrollValue(Math.round(value))}
347
+ />
348
+ </div>
349
+ <span className="docs-demo-value">value: {scrollValue}</span>
350
+ </>
351
+ );
352
+ }
353
+
280
354
  type DemoProps = {
281
355
  code: React.ReactNode;
282
356
  stageClass?: string;
@@ -1085,60 +1159,73 @@ function App() {
1085
1159
  <h2 className="docs-section-title">Navigation</h2>
1086
1160
  <p className="docs-section-desc">
1087
1161
  Horizontal navigation for top-of-page links. The active option is
1088
- underlined with the brand color; hover an option that owns a
1089
- submenu to reveal it.
1162
+ underlined with the brand color; click an option that owns a
1163
+ submenu to open it.
1090
1164
  </p>
1091
1165
  <Demo
1092
1166
  stageClass="column"
1093
- code={`<ul className="gc-navigation gc-navigation--default">
1094
- <li className="gc-navigation__option gc-navigation__option--active">
1095
- <a className="gc-navigation__link" href="#">Overview</a>
1096
- </li>
1097
- <li className="gc-navigation__option">
1098
- <a className="gc-navigation__link" href="#">Components</a>
1099
- <div className="gc-submenu">
1100
- <div className="gc-submenu__content">
1101
- <a className="gc-submenu__item" href="#">Button</a>
1102
- <a className="gc-submenu__item" href="#">Card</a>
1103
- <a className="gc-submenu__item" href="#">Dialog</a>
1104
- </div>
1105
- </div>
1106
- </li>
1107
- <li className="gc-navigation__option">
1108
- <a className="gc-navigation__link" href="#">Resources</a>
1109
- </li>
1110
- </ul>`}
1167
+ code={`<Navigation>
1168
+ <NavigationOption label="Overview" href="#" isActive />
1169
+ <NavigationOption label="Components">
1170
+ <a className="gc-submenu__item" href="#">Button</a>
1171
+ <a className="gc-submenu__item" href="#">Card</a>
1172
+ <a className="gc-submenu__item" href="#">Dialog</a>
1173
+ </NavigationOption>
1174
+ <NavigationOption label="Resources" href="#" />
1175
+ </Navigation>`}
1111
1176
  >
1112
- <ul className="gc-navigation gc-navigation--default">
1113
- <li className="gc-navigation__option gc-navigation__option--active">
1114
- <a className="gc-navigation__link" href="#">
1115
- Overview
1177
+ <Navigation>
1178
+ <NavigationOption label="Overview" href="#" isActive />
1179
+ <NavigationOption label="Components">
1180
+ <a className="gc-submenu__item" href="#">
1181
+ Button
1116
1182
  </a>
1117
- </li>
1118
- <li className="gc-navigation__option">
1119
- <a className="gc-navigation__link" href="#">
1120
- Components
1183
+ <a className="gc-submenu__item" href="#">
1184
+ Card
1121
1185
  </a>
1122
- <div className="gc-submenu">
1123
- <div className="gc-submenu__content">
1124
- <a className="gc-submenu__item" href="#">
1125
- Button
1126
- </a>
1127
- <a className="gc-submenu__item" href="#">
1128
- Card
1129
- </a>
1130
- <a className="gc-submenu__item" href="#">
1131
- Dialog
1132
- </a>
1133
- </div>
1134
- </div>
1135
- </li>
1136
- <li className="gc-navigation__option">
1137
- <a className="gc-navigation__link" href="#">
1138
- Resources
1186
+ <a className="gc-submenu__item" href="#">
1187
+ Dialog
1139
1188
  </a>
1140
- </li>
1141
- </ul>
1189
+ </NavigationOption>
1190
+ <NavigationOption label="Resources" href="#" />
1191
+ </Navigation>
1192
+ </Demo>
1193
+ <p className="docs-section-desc">
1194
+ Inside a narrow container the navigation scrolls horizontally. The
1195
+ submenu follows its scrolled parent option and stays within the
1196
+ viewport.
1197
+ </p>
1198
+ <Demo
1199
+ stageClass="column"
1200
+ code={`<div style={{ maxWidth: 280, overflowX: "auto" }}>
1201
+ <Navigation>
1202
+ <NavigationOption label="Overview" href="#" isActive />
1203
+ <NavigationOption label="Admin" href="#" />
1204
+ <NavigationOption label="Platform">
1205
+ <a className="gc-submenu__item" href="#">Users</a>
1206
+ <a className="gc-submenu__item" href="#">Events</a>
1207
+ </NavigationOption>
1208
+ <NavigationOption label="e-Shop" href="#" />
1209
+ <NavigationOption label="Account" href="#" />
1210
+ </Navigation>
1211
+ </div>`}
1212
+ >
1213
+ <div style={{ maxWidth: 280, overflowX: "auto" }}>
1214
+ <Navigation>
1215
+ <NavigationOption label="Overview" href="#" isActive />
1216
+ <NavigationOption label="Admin" href="#" />
1217
+ <NavigationOption label="Platform">
1218
+ <a className="gc-submenu__item" href="#">
1219
+ Users
1220
+ </a>
1221
+ <a className="gc-submenu__item" href="#">
1222
+ Events
1223
+ </a>
1224
+ </NavigationOption>
1225
+ <NavigationOption label="e-Shop" href="#" />
1226
+ <NavigationOption label="Account" href="#" />
1227
+ </Navigation>
1228
+ </div>
1142
1229
  </Demo>
1143
1230
  </section>
1144
1231
 
@@ -1237,6 +1324,306 @@ function App() {
1237
1324
  </Demo>
1238
1325
  </section>
1239
1326
 
1327
+ <section className="docs-section" id="panel">
1328
+ <div className="docs-section-eyebrow">Components / 16</div>
1329
+ <h2 className="docs-section-title">Panel</h2>
1330
+ <p className="docs-section-desc">
1331
+ A composable surface for grouping related content. Combine{" "}
1332
+ <code>PanelTitle</code>, <code>PanelContent</code> and{" "}
1333
+ <code>PanelFooter</code>; <code>isBordered</code> outlines the
1334
+ panel and <code>isSeparator</code> draws dividers between the
1335
+ parts.
1336
+ </p>
1337
+ <Demo
1338
+ stageClass="column"
1339
+ code={`<Panel isBordered>
1340
+ <PanelTitle>Billing</PanelTitle>
1341
+ <PanelContent>Invoices are issued on the first day of each month.</PanelContent>
1342
+ <PanelFooter>Last updated today</PanelFooter>
1343
+ </Panel>
1344
+ <Panel isSeparator>
1345
+ <PanelTitle>Notifications</PanelTitle>
1346
+ <PanelContent>Choose how you want to be notified about activity.</PanelContent>
1347
+ </Panel>`}
1348
+ >
1349
+ <Panel isBordered>
1350
+ <PanelTitle>Billing</PanelTitle>
1351
+ <PanelContent>
1352
+ Invoices are issued on the first day of each month.
1353
+ </PanelContent>
1354
+ <PanelFooter>Last updated today</PanelFooter>
1355
+ </Panel>
1356
+ <Panel isSeparator>
1357
+ <PanelTitle>Notifications</PanelTitle>
1358
+ <PanelContent>
1359
+ Choose how you want to be notified about activity.
1360
+ </PanelContent>
1361
+ </Panel>
1362
+ </Demo>
1363
+ </section>
1364
+
1365
+ <section className="docs-section" id="accordion">
1366
+ <div className="docs-section-eyebrow">Components / 17</div>
1367
+ <h2 className="docs-section-title">Accordion</h2>
1368
+ <p className="docs-section-desc">
1369
+ A collapsible panel for secondary content. It starts collapsed by
1370
+ default — click the title to expand it.
1371
+ </p>
1372
+ <Demo
1373
+ stageClass="column"
1374
+ code={`<Accordion title="Shipping details">
1375
+ Orders placed before noon ship the same day. Tracking is emailed
1376
+ once the parcel leaves the warehouse.
1377
+ </Accordion>`}
1378
+ >
1379
+ <Accordion title="Shipping details">
1380
+ Orders placed before noon ship the same day. Tracking is emailed
1381
+ once the parcel leaves the warehouse.
1382
+ </Accordion>
1383
+ </Demo>
1384
+ </section>
1385
+
1386
+ <section className="docs-section" id="flex">
1387
+ <div className="docs-section-eyebrow">Components / 18</div>
1388
+ <h2 className="docs-section-title">Flex</h2>
1389
+ <p className="docs-section-desc">
1390
+ A thin flexbox wrapper. <code>FlexItem</code> children opt into
1391
+ growing or shrinking; <code>isVertical</code> stacks them as a
1392
+ column.
1393
+ </p>
1394
+ <Demo
1395
+ stageClass="column"
1396
+ code={`<Flex>
1397
+ <FlexItem>aside</FlexItem>
1398
+ <FlexItem isGrow>main content</FlexItem>
1399
+ <FlexItem>aside</FlexItem>
1400
+ </Flex>
1401
+ <Flex isVertical>
1402
+ <FlexItem>row one</FlexItem>
1403
+ <FlexItem>row two</FlexItem>
1404
+ </Flex>`}
1405
+ >
1406
+ <Flex className="docs-flex-demo">
1407
+ <FlexItem className="docs-flex-box">aside</FlexItem>
1408
+ <FlexItem className="docs-flex-box" isGrow>
1409
+ main content
1410
+ </FlexItem>
1411
+ <FlexItem className="docs-flex-box">aside</FlexItem>
1412
+ </Flex>
1413
+ <Flex isVertical>
1414
+ <FlexItem className="docs-flex-box">row one</FlexItem>
1415
+ <FlexItem className="docs-flex-box">row two</FlexItem>
1416
+ </Flex>
1417
+ </Demo>
1418
+ </section>
1419
+
1420
+ <section className="docs-section" id="loader">
1421
+ <div className="docs-section-eyebrow">Components / 19</div>
1422
+ <h2 className="docs-section-title">Loader</h2>
1423
+ <p className="docs-section-desc">
1424
+ An indeterminate spinner for blocking waits. The ring mixes white
1425
+ and gray strokes, so it reads best on dark or tinted surfaces.
1426
+ </p>
1427
+ <Demo stageClass="center" code="<Loader />">
1428
+ <div className="docs-loader-stage">
1429
+ <Loader />
1430
+ </div>
1431
+ </Demo>
1432
+ </section>
1433
+
1434
+ <section className="docs-section" id="skeleton">
1435
+ <div className="docs-section-eyebrow">Components / 20</div>
1436
+ <h2 className="docs-section-title">Skeleton</h2>
1437
+ <p className="docs-section-desc">
1438
+ A shimmering placeholder line for content that is still loading.
1439
+ Compose several with varying widths to sketch the final layout.
1440
+ </p>
1441
+ <Demo
1442
+ stageClass="column"
1443
+ code={`<Skeleton />
1444
+ <Skeleton />
1445
+ <Skeleton />`}
1446
+ >
1447
+ <div className="docs-skeleton-demo">
1448
+ <Skeleton />
1449
+ <Skeleton />
1450
+ <Skeleton />
1451
+ </div>
1452
+ </Demo>
1453
+ </section>
1454
+
1455
+ <section className="docs-section" id="tooltip">
1456
+ <div className="docs-section-eyebrow">Components / 21</div>
1457
+ <h2 className="docs-section-title">Tooltip</h2>
1458
+ <p className="docs-section-desc">
1459
+ A small anchored bubble for contextual feedback. It positions
1460
+ absolutely against the nearest positioned ancestor; the{" "}
1461
+ <code>type</code> prop keys the color to the semantic palette.
1462
+ </p>
1463
+ <Demo
1464
+ code={`<Tooltip type="success">Saved successfully</Tooltip>
1465
+ <Tooltip type="danger">Something went wrong</Tooltip>`}
1466
+ >
1467
+ <div className="docs-tooltip-anchor">
1468
+ <Tooltip type="success">Saved successfully</Tooltip>
1469
+ </div>
1470
+ <div className="docs-tooltip-anchor">
1471
+ <Tooltip type="danger">Something went wrong</Tooltip>
1472
+ </div>
1473
+ </Demo>
1474
+ </section>
1475
+
1476
+ <section className="docs-section" id="validation">
1477
+ <div className="docs-section-eyebrow">Components / 22</div>
1478
+ <h2 className="docs-section-title">Validation</h2>
1479
+ <p className="docs-section-desc">
1480
+ Wraps a form control and reveals a tooltip with the validation
1481
+ message on hover. Hover the inputs below to see it.
1482
+ </p>
1483
+ <Demo
1484
+ stageClass="column"
1485
+ code={`<Validation type="danger" message="Email is required">
1486
+ <Input label="Email" type="email" validation="danger" />
1487
+ </Validation>
1488
+ <Validation type="success" message="Looks good">
1489
+ <Input label="Username" type="text" validation="success" />
1490
+ </Validation>`}
1491
+ >
1492
+ <Validation type="danger" message="Email is required">
1493
+ <Input label="Email" type="email" validation="danger" />
1494
+ </Validation>
1495
+ <Validation type="success" message="Looks good">
1496
+ <Input label="Username" type="text" validation="success" />
1497
+ </Validation>
1498
+ </Demo>
1499
+ </section>
1500
+
1501
+ <section className="docs-section" id="alert">
1502
+ <div className="docs-section-eyebrow">Components / 23</div>
1503
+ <h2 className="docs-section-title">Alert</h2>
1504
+ <p className="docs-section-desc">
1505
+ A bordered message box for inline page-level feedback. Styles-only
1506
+ primitive — apply the classes to your own markup.
1507
+ </p>
1508
+ <Demo
1509
+ stageClass="column"
1510
+ code={`<div className="gc-alert gc-alert--info">A new version is available.</div>
1511
+ <div className="gc-alert gc-alert--success">Settings saved.</div>
1512
+ <div className="gc-alert gc-alert--danger">Could not reach the server.</div>`}
1513
+ >
1514
+ <div className="gc-alert gc-alert--info">
1515
+ A new version is available.
1516
+ </div>
1517
+ <div className="gc-alert gc-alert--success">Settings saved.</div>
1518
+ <div className="gc-alert gc-alert--danger">
1519
+ Could not reach the server.
1520
+ </div>
1521
+ </Demo>
1522
+ </section>
1523
+
1524
+ <section className="docs-section" id="list">
1525
+ <div className="docs-section-eyebrow">Components / 24</div>
1526
+ <h2 className="docs-section-title">List</h2>
1527
+ <p className="docs-section-desc">
1528
+ A bordered stack of rows for simple records. Styles-only primitive
1529
+ — apply the classes to your own markup.
1530
+ </p>
1531
+ <Demo
1532
+ stageClass="column"
1533
+ code={`<ul className="gc-list">
1534
+ <li className="gc-list__item">Production deploy</li>
1535
+ <li className="gc-list__item">Staging deploy</li>
1536
+ <li className="gc-list__item">Nightly backup</li>
1537
+ </ul>`}
1538
+ >
1539
+ <ul className="gc-list docs-list-demo">
1540
+ <li className="gc-list__item">Production deploy</li>
1541
+ <li className="gc-list__item">Staging deploy</li>
1542
+ <li className="gc-list__item">Nightly backup</li>
1543
+ </ul>
1544
+ </Demo>
1545
+ </section>
1546
+
1547
+ <section className="docs-section" id="textarea">
1548
+ <div className="docs-section-eyebrow">Components / 25</div>
1549
+ <h2 className="docs-section-title">Textarea</h2>
1550
+ <p className="docs-section-desc">
1551
+ Multi-line text input matching the Input styling. Styles-only
1552
+ primitive — apply the class to a native textarea.
1553
+ </p>
1554
+ <Demo
1555
+ stageClass="column"
1556
+ code={`<textarea className="gc-textarea" rows={3} placeholder="Describe the issue…" />`}
1557
+ >
1558
+ <textarea
1559
+ className="gc-textarea"
1560
+ rows={3}
1561
+ placeholder="Describe the issue…"
1562
+ />
1563
+ </Demo>
1564
+ </section>
1565
+
1566
+ <section className="docs-section" id="led">
1567
+ <div className="docs-section-eyebrow">Components / 26</div>
1568
+ <h2 className="docs-section-title">LED</h2>
1569
+ <p className="docs-section-desc">
1570
+ A status light for dashboards and device panels. Add{" "}
1571
+ <code>gc-led--blink</code> for attention-demanding states.
1572
+ Styles-only primitive.
1573
+ </p>
1574
+ <Demo
1575
+ stageClass="center"
1576
+ code={`<span className="gc-led gc-led--green" />
1577
+ <span className="gc-led gc-led--blue" />
1578
+ <span className="gc-led gc-led--red" />
1579
+ <span className="gc-led gc-led--red gc-led--blink" />`}
1580
+ >
1581
+ <span className="gc-led gc-led--green" />
1582
+ <span className="gc-led gc-led--blue" />
1583
+ <span className="gc-led gc-led--red" />
1584
+ <span className="gc-led gc-led--red gc-led--blink" />
1585
+ </Demo>
1586
+ </section>
1587
+
1588
+ <section className="docs-section" id="joystick">
1589
+ <div className="docs-section-eyebrow">Components / 27</div>
1590
+ <h2 className="docs-section-title">Joystick</h2>
1591
+ <p className="docs-section-desc">
1592
+ A draggable two-axis control for hardware-like interfaces. Drag
1593
+ the knob — the position is reported through{" "}
1594
+ <code>onPositionChange</code>.
1595
+ </p>
1596
+ <Demo
1597
+ stageClass="center"
1598
+ code={`<Joystick
1599
+ isEnabled
1600
+ onPositionChange={(left, top) => console.log(left, top)}
1601
+ />`}
1602
+ >
1603
+ <JoystickDemo />
1604
+ </Demo>
1605
+ </section>
1606
+
1607
+ <section className="docs-section" id="scroller">
1608
+ <div className="docs-section-eyebrow">Components / 28</div>
1609
+ <h2 className="docs-section-title">Scroller</h2>
1610
+ <p className="docs-section-desc">
1611
+ A draggable horizontal slider for scrubbing through a range. Drag
1612
+ the knob — the position is reported through{" "}
1613
+ <code>onScrollChange</code> when the knob is released.
1614
+ </p>
1615
+ <Demo
1616
+ stageClass="center"
1617
+ code={`<Scroller
1618
+ min={0}
1619
+ max={100}
1620
+ onScrollChange={(value) => console.log(value)}
1621
+ />`}
1622
+ >
1623
+ <ScrollerDemo />
1624
+ </Demo>
1625
+ </section>
1626
+
1240
1627
  <footer className="docs-footer">
1241
1628
  <div>graphen · {VERSION} · MIT</div>
1242
1629
  <div>Built by the CODA_ team</div>
package/src/index.ts CHANGED
@@ -14,6 +14,8 @@ import Separator from "src/components/Separator";
14
14
  import Tooltip from "src/components/Tooltip";
15
15
  import Validation from "src/components/Validation";
16
16
  import Logo from "src/components/Logo";
17
+ import Navigation from "src/components/Navigation";
18
+ import NavigationOption from "src/components/NavigationOption";
17
19
  import Dropdown from "src/components/Dropdown";
18
20
  import Flex from "src/components/Flex";
19
21
  import FlexItem from "src/components/FlexItem";
@@ -45,6 +47,8 @@ export {
45
47
  Tooltip,
46
48
  Validation,
47
49
  Logo,
50
+ Navigation,
51
+ NavigationOption,
48
52
  Dropdown,
49
53
  Flex,
50
54
  FlexItem,
@@ -1,6 +1,6 @@
1
1
  describe("Colors", () => {
2
2
  before(() => {
3
- cy.visit("http://localhost:3000");
3
+ cy.visit("/");
4
4
  });
5
5
 
6
6
  it("should make a screenshot", () => {