@mshuja288/aksuicore 0.2.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ Versioning follows [VERSIONING.md](./VERSIONING.md).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] — 2026-10-12
11
+
12
+ ### Added
13
+
14
+ - `RecordWorkspace` column picker: toggle visible columns (default all), optional `columnPrefsKey` persistence, `exportKey` / `ExportColumnRef`
15
+ - `onDownload(format, columns)` now passes the currently visible columns for smart exports
16
+ - `AppShell` mobile drawer navigation (`mobileNav="drawer"` default) with topbar hamburger — avoids crowded bottom nav on many sections
17
+ - Compact mobile row actions (⋯ menu) in `RecordWorkspace`
18
+
19
+ ### Changed
20
+
21
+ - Small screens: side-rail actions sit above the table; sticky Actions column; bottom nav only when `mobileNav` is `bottom` or `hybrid`
22
+
23
+ ## [0.3.0] — 2026-10-12
24
+
25
+ ### Added
26
+
27
+ - `RecordWorkspace` download control: optional `onDownload(format)` with CSV / Excel / JSON choices in the side rail (`ExportDownloadFormat` type exported)
28
+
10
29
  ## [0.2.1] — 2026-10-05
11
30
 
12
31
  ### Added
package/README.md CHANGED
@@ -4,7 +4,7 @@ Shared React UI library for Ikssam apps — reusable **primitives** and **templa
4
4
 
5
5
  ## Status
6
6
 
7
- `v0.2.0` — package renamed to `@mshuja288/aksuicore`. Published on npmjs. See [CHANGELOG.md](./CHANGELOG.md).
7
+ `v0.3.0` — RecordWorkspace download (CSV / Excel / JSON). Published on npmjs. See [CHANGELOG.md](./CHANGELOG.md).
8
8
 
9
9
  ## AppShell API
10
10
 
package/dist/aksui.css CHANGED
@@ -101,13 +101,17 @@ button.ghost:hover,
101
101
  button.app-select-trigger:hover,
102
102
  button.date-field-trigger:hover,
103
103
  button.avatar-button:hover,
104
+ button.topbar-menu-button:hover,
104
105
  button.sort-header:hover,
105
106
  button.row-action:hover,
107
+ button.row-action-menu-trigger:hover,
106
108
  button.date-picker-day:hover,
107
109
  button.side-rail-toggle:hover,
108
110
  button.side-rail-icon:hover,
111
+ button.side-rail-columns-toggle:hover,
109
112
  button.filter-clear:hover,
110
- button.snackbar-close:hover {
113
+ button.snackbar-close:hover,
114
+ button.nav-drawer-close:hover {
111
115
  transform: none;
112
116
  }
113
117
 
@@ -225,6 +229,10 @@ select:disabled {
225
229
  min-width: 0;
226
230
  }
227
231
 
232
+ button.topbar-menu-button {
233
+ flex: 0 0 auto;
234
+ }
235
+
228
236
  .topbar-logo {
229
237
  width: 40px;
230
238
  height: 40px;
@@ -1211,6 +1219,135 @@ button.side-rail-add:hover {
1211
1219
  background: #2a3546;
1212
1220
  }
1213
1221
 
1222
+ .side-rail-columns,
1223
+ .side-rail-download {
1224
+ display: grid;
1225
+ gap: 8px;
1226
+ }
1227
+
1228
+ button.side-rail-columns-toggle {
1229
+ display: inline-flex;
1230
+ align-items: center;
1231
+ justify-content: center;
1232
+ gap: 8px;
1233
+ width: 100%;
1234
+ padding: 10px 12px;
1235
+ border: 1px solid var(--aks-border, #d7dde5);
1236
+ border-radius: var(--aks-radius);
1237
+ background: #fff;
1238
+ color: var(--aks-brand);
1239
+ box-shadow: none;
1240
+ }
1241
+
1242
+ button.side-rail-columns-toggle svg {
1243
+ width: 18px;
1244
+ height: 18px;
1245
+ }
1246
+
1247
+ button.side-rail-columns-toggle:hover {
1248
+ background: #f5f7fa;
1249
+ }
1250
+
1251
+ .side-rail-columns-panel {
1252
+ display: grid;
1253
+ gap: 8px;
1254
+ padding: 8px;
1255
+ border: 1px solid var(--aks-line);
1256
+ border-radius: var(--aks-radius);
1257
+ background: #faf9f7;
1258
+ }
1259
+
1260
+ .side-rail-columns-actions {
1261
+ display: flex;
1262
+ gap: 6px;
1263
+ }
1264
+
1265
+ .side-rail-columns-actions button {
1266
+ flex: 1 1 auto;
1267
+ padding: 6px 8px;
1268
+ font-size: 12px;
1269
+ box-shadow: none;
1270
+ }
1271
+
1272
+ .side-rail-columns-list {
1273
+ display: grid;
1274
+ gap: 6px;
1275
+ max-height: 220px;
1276
+ overflow: auto;
1277
+ }
1278
+
1279
+ label.side-rail-column-option {
1280
+ display: flex;
1281
+ align-items: center;
1282
+ gap: 8px;
1283
+ margin: 0;
1284
+ padding: 4px 2px;
1285
+ color: var(--aks-brand);
1286
+ font-size: 13px;
1287
+ font-weight: 500;
1288
+ }
1289
+
1290
+ label.side-rail-column-option input {
1291
+ width: auto;
1292
+ min-height: 0;
1293
+ margin: 0;
1294
+ accent-color: var(--aks-accent);
1295
+ }
1296
+
1297
+ button.side-rail-download-toggle {
1298
+ display: inline-flex;
1299
+ align-items: center;
1300
+ justify-content: center;
1301
+ gap: 8px;
1302
+ width: 100%;
1303
+ padding: 10px 12px;
1304
+ border: 1px solid var(--aks-border, #d7dde5);
1305
+ border-radius: var(--aks-radius);
1306
+ background: #fff;
1307
+ color: var(--aks-brand);
1308
+ box-shadow: none;
1309
+ }
1310
+
1311
+ button.side-rail-download-toggle svg {
1312
+ width: 18px;
1313
+ height: 18px;
1314
+ }
1315
+
1316
+ button.side-rail-download-toggle:hover:not(:disabled) {
1317
+ background: #f5f7fa;
1318
+ }
1319
+
1320
+ button.side-rail-download-toggle:disabled {
1321
+ opacity: 0.55;
1322
+ cursor: default;
1323
+ }
1324
+
1325
+ .side-rail-download-formats {
1326
+ display: grid;
1327
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1328
+ gap: 6px;
1329
+ }
1330
+
1331
+ button.side-rail-download-format {
1332
+ padding: 8px 6px;
1333
+ border: 1px solid var(--aks-border, #d7dde5);
1334
+ border-radius: var(--aks-radius);
1335
+ background: #fff;
1336
+ color: var(--aks-brand);
1337
+ font-size: 12px;
1338
+ font-weight: 600;
1339
+ box-shadow: none;
1340
+ }
1341
+
1342
+ button.side-rail-download-format:hover:not(:disabled) {
1343
+ background: #f5f7fa;
1344
+ }
1345
+
1346
+ button.side-rail-download-format:disabled {
1347
+ opacity: 0.45;
1348
+ cursor: default;
1349
+ }
1350
+
1214
1351
  .side-rail-filters {
1215
1352
  display: grid;
1216
1353
  gap: 12px;
@@ -1412,6 +1549,65 @@ button.sort-header.active .sort-indicator {
1412
1549
  gap: 6px;
1413
1550
  }
1414
1551
 
1552
+ .row-actions-mobile {
1553
+ display: none;
1554
+ position: relative;
1555
+ }
1556
+
1557
+ button.row-action-menu-trigger {
1558
+ width: 36px;
1559
+ height: 32px;
1560
+ padding: 0;
1561
+ color: var(--aks-muted);
1562
+ box-shadow: none;
1563
+ }
1564
+
1565
+ button.row-action-menu-trigger svg {
1566
+ width: 18px;
1567
+ height: 18px;
1568
+ }
1569
+
1570
+ button.row-action-menu-trigger:hover {
1571
+ transform: none;
1572
+ background: #f4f2ef;
1573
+ color: var(--aks-brand);
1574
+ box-shadow: none;
1575
+ }
1576
+
1577
+ .row-action-menu {
1578
+ position: absolute;
1579
+ top: calc(100% + 4px);
1580
+ right: 0;
1581
+ z-index: 5;
1582
+ display: grid;
1583
+ min-width: 132px;
1584
+ padding: 6px;
1585
+ border: 1px solid var(--aks-line);
1586
+ border-radius: var(--aks-radius);
1587
+ background: #fff;
1588
+ box-shadow: 0 12px 28px rgba(30, 39, 53, 0.14);
1589
+ }
1590
+
1591
+ .row-action-menu button {
1592
+ justify-content: flex-start;
1593
+ width: 100%;
1594
+ padding: 8px 10px;
1595
+ font-size: 13px;
1596
+ font-weight: 600;
1597
+ color: var(--aks-brand);
1598
+ box-shadow: none;
1599
+ }
1600
+
1601
+ .row-action-menu button.danger:not(:disabled) {
1602
+ color: #a33b2b;
1603
+ }
1604
+
1605
+ .row-action-menu button:hover:not(:disabled) {
1606
+ transform: none;
1607
+ background: #f4f2ef;
1608
+ box-shadow: none;
1609
+ }
1610
+
1415
1611
  button.row-action {
1416
1612
  padding: 4px 8px;
1417
1613
  font-size: 12px;
@@ -1509,6 +1705,10 @@ button.row-action.danger:not(:disabled):hover {
1509
1705
  }
1510
1706
 
1511
1707
  @media (max-width: 900px) {
1708
+ .list-body {
1709
+ flex-direction: column;
1710
+ }
1711
+
1512
1712
  .list-body.side-open,
1513
1713
  .list-body.preview-open {
1514
1714
  flex-direction: column;
@@ -1526,16 +1726,47 @@ button.row-action.danger:not(:disabled):hover {
1526
1726
  align-items: center;
1527
1727
  width: 100%;
1528
1728
  flex-basis: auto;
1729
+ order: -1;
1529
1730
  }
1530
1731
 
1531
1732
  .side-rail:not(.open) .side-rail-icons {
1532
1733
  display: inline-flex;
1734
+ flex-wrap: wrap;
1533
1735
  margin-left: auto;
1736
+ gap: 4px;
1737
+ }
1738
+
1739
+ .side-rail.open {
1740
+ order: -1;
1534
1741
  }
1535
1742
 
1536
1743
  .table-card-bar {
1537
1744
  flex-wrap: wrap;
1538
1745
  }
1746
+
1747
+ .data-table {
1748
+ min-width: 520px;
1749
+ }
1750
+
1751
+ .row-actions-desktop {
1752
+ display: none;
1753
+ }
1754
+
1755
+ .row-actions-mobile {
1756
+ display: inline-flex;
1757
+ }
1758
+
1759
+ .data-table .actions-col {
1760
+ position: sticky;
1761
+ right: 0;
1762
+ z-index: 1;
1763
+ background: #fff;
1764
+ box-shadow: -8px 0 12px rgba(30, 39, 53, 0.04);
1765
+ }
1766
+
1767
+ .data-table thead .actions-col {
1768
+ background: #f6f5f3;
1769
+ }
1539
1770
  }
1540
1771
 
1541
1772
  /* src\theme\shell.css */
@@ -1574,20 +1805,146 @@ button.row-action.danger:not(:disabled):hover {
1574
1805
  display: none;
1575
1806
  }
1576
1807
 
1808
+ /* Mobile drawer — hidden on desktop */
1809
+ .nav-drawer-backdrop,
1810
+ .nav-drawer {
1811
+ display: none;
1812
+ }
1813
+
1814
+ button.topbar-menu-button {
1815
+ display: none;
1816
+ width: 40px;
1817
+ height: 40px;
1818
+ padding: 0;
1819
+ border-radius: var(--aks-radius);
1820
+ background: transparent;
1821
+ color: var(--aks-brand);
1822
+ box-shadow: none;
1823
+ }
1824
+
1825
+ button.topbar-menu-button svg {
1826
+ width: 22px;
1827
+ height: 22px;
1828
+ }
1829
+
1830
+ button.topbar-menu-button:hover {
1831
+ transform: none;
1832
+ background: #f4f2ef;
1833
+ box-shadow: none;
1834
+ }
1835
+
1577
1836
  @media (max-width: 900px) {
1578
1837
  .app-body {
1579
1838
  grid-template-columns: 1fr;
1580
1839
  }
1581
1840
 
1582
- .app-shell .side-nav {
1841
+ .app-shell .app-body > .side-nav {
1583
1842
  display: none;
1584
1843
  }
1585
1844
 
1586
- .app-shell .screen {
1845
+ button.topbar-menu-button {
1846
+ display: inline-grid;
1847
+ place-items: center;
1848
+ }
1849
+
1850
+ .app-shell.mobile-nav-drawer .screen,
1851
+ .app-shell.mobile-nav-hybrid:not(.has-bottom-nav) .screen {
1852
+ padding: 10px;
1853
+ }
1854
+
1855
+ .app-shell.has-bottom-nav .screen {
1587
1856
  padding: 10px 10px 88px;
1588
1857
  }
1589
1858
 
1590
- .bottom-nav {
1859
+ /* Drawer overlay */
1860
+ .nav-drawer-backdrop {
1861
+ display: block;
1862
+ position: fixed;
1863
+ inset: 0;
1864
+ z-index: 40;
1865
+ border: 0;
1866
+ padding: 0;
1867
+ margin: 0;
1868
+ background: rgba(30, 39, 53, 0.42);
1869
+ opacity: 0;
1870
+ pointer-events: none;
1871
+ transition: opacity 160ms ease;
1872
+ box-shadow: none;
1873
+ }
1874
+
1875
+ .nav-drawer-backdrop.open {
1876
+ opacity: 1;
1877
+ pointer-events: auto;
1878
+ }
1879
+
1880
+ .nav-drawer {
1881
+ display: flex;
1882
+ flex-direction: column;
1883
+ position: fixed;
1884
+ top: 0;
1885
+ left: 0;
1886
+ bottom: 0;
1887
+ z-index: 50;
1888
+ width: min(300px, calc(100vw - 48px));
1889
+ background: #fff;
1890
+ border-right: 1px solid var(--aks-line);
1891
+ box-shadow: 12px 0 32px rgba(30, 39, 53, 0.18);
1892
+ transform: translateX(-105%);
1893
+ transition: transform 180ms ease;
1894
+ pointer-events: none;
1895
+ }
1896
+
1897
+ .nav-drawer.open {
1898
+ transform: translateX(0);
1899
+ pointer-events: auto;
1900
+ }
1901
+
1902
+ .nav-drawer-head {
1903
+ display: flex;
1904
+ align-items: center;
1905
+ justify-content: space-between;
1906
+ gap: 12px;
1907
+ flex: 0 0 auto;
1908
+ padding: 14px 14px 10px;
1909
+ border-bottom: 1px solid var(--aks-line);
1910
+ }
1911
+
1912
+ .nav-drawer-title {
1913
+ margin: 0;
1914
+ color: var(--aks-brand);
1915
+ font-size: 12px;
1916
+ font-weight: 700;
1917
+ letter-spacing: 0.06em;
1918
+ text-transform: uppercase;
1919
+ }
1920
+
1921
+ button.nav-drawer-close {
1922
+ padding: 6px 10px;
1923
+ font-size: 12px;
1924
+ box-shadow: none;
1925
+ }
1926
+
1927
+ .nav-drawer .side-nav,
1928
+ .nav-drawer-nav {
1929
+ display: flex !important;
1930
+ flex-direction: column;
1931
+ flex: 1 1 auto;
1932
+ min-height: 0;
1933
+ overflow: auto;
1934
+ padding: 10px;
1935
+ gap: 4px;
1936
+ border: 0;
1937
+ background: transparent;
1938
+ }
1939
+
1940
+ .nav-drawer .side-nav button {
1941
+ justify-content: flex-start;
1942
+ width: 100%;
1943
+ text-align: left;
1944
+ }
1945
+
1946
+ /* Legacy / optional bottom nav */
1947
+ .app-shell.has-bottom-nav .bottom-nav {
1591
1948
  position: fixed;
1592
1949
  left: 0;
1593
1950
  right: 0;
@@ -1602,6 +1959,10 @@ button.row-action.danger:not(:disabled):hover {
1602
1959
  box-shadow: 0 -8px 24px rgba(30, 39, 53, 0.18);
1603
1960
  }
1604
1961
 
1962
+ .app-shell.mobile-nav-hybrid.has-bottom-nav .bottom-nav {
1963
+ grid-template-columns: 1fr auto;
1964
+ }
1965
+
1605
1966
  .bottom-nav button {
1606
1967
  display: flex;
1607
1968
  flex-direction: column;
@@ -1615,18 +1976,37 @@ button.row-action.danger:not(:disabled):hover {
1615
1976
  font-size: 10px;
1616
1977
  line-height: 1.1;
1617
1978
  white-space: nowrap;
1979
+ overflow: hidden;
1980
+ text-overflow: ellipsis;
1618
1981
  box-shadow: none;
1619
1982
  }
1620
1983
 
1984
+ .bottom-nav button.bottom-nav-current {
1985
+ align-items: flex-start;
1986
+ padding-left: 14px;
1987
+ font-size: 12px;
1988
+ font-weight: 600;
1989
+ color: #fff;
1990
+ opacity: 1;
1991
+ }
1992
+
1993
+ .bottom-nav button.bottom-nav-menu {
1994
+ min-width: 72px;
1995
+ background: var(--aks-accent);
1996
+ color: #fff;
1997
+ font-size: 12px;
1998
+ font-weight: 700;
1999
+ }
2000
+
1621
2001
  .bottom-nav button.active,
1622
- .bottom-nav button:hover {
2002
+ .bottom-nav button:hover:not(:disabled) {
1623
2003
  transform: none;
1624
2004
  background: var(--aks-accent);
1625
2005
  color: #fff;
1626
2006
  box-shadow: none;
1627
2007
  }
1628
2008
 
1629
- .snackbar-host {
2009
+ .app-shell.has-bottom-nav .snackbar-host {
1630
2010
  right: 16px;
1631
2011
  bottom: calc(78px + env(safe-area-inset-bottom));
1632
2012
  }