@0001-labs/design-system-1 0.3.0-alpha.27 → 0.3.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/DS1/0-face/button-label.ts +28 -0
- package/DS1/0-face/calendar.ts +6 -4
- package/DS1/0-face/carousel.ts +70 -0
- package/DS1/0-face/constraint-panel.ts +422 -0
- package/DS1/0-face/constraint-site.ts +200 -0
- package/DS1/0-face/constraints.ts +281 -0
- package/DS1/0-face/copy-text.ts +1 -1
- package/DS1/0-face/cut-fade.ts +312 -0
- package/DS1/0-face/define.ts +30 -2
- package/DS1/0-face/face-correction.ts +96 -0
- package/DS1/0-face/failures.ts +32 -0
- package/DS1/0-face/feedback-overlays.ts +5 -3
- package/DS1/0-face/feedback.ts +3 -0
- package/DS1/0-face/focus-vision.swift +31 -0
- package/DS1/0-face/focus.ts +181 -0
- package/DS1/0-face/google-face-metrics.json +102 -0
- package/DS1/0-face/grid.ts +61 -4
- package/DS1/0-face/i18n.ts +36 -18
- package/DS1/0-face/layout-inspector.ts +124 -98
- package/DS1/0-face/preference-options.ts +4 -0
- package/DS1/0-face/scaling.ts +21 -3
- package/DS1/0-face/shape.ts +43 -0
- package/DS1/0-face/text-contrast.ts +164 -0
- package/DS1/0-face/theme-bootstrap.js +43 -0
- package/DS1/0-face/toast-queue.ts +7 -1
- package/DS1/0-face/translations/da.json +10 -1
- package/DS1/0-face/translations/de.json +10 -1
- package/DS1/0-face/translations/en.json +10 -1
- package/DS1/0-face/translations/es.json +10 -1
- package/DS1/0-face/translations/fi.json +10 -1
- package/DS1/0-face/translations/fr.json +10 -1
- package/DS1/0-face/translations/is.json +10 -1
- package/DS1/0-face/translations/it.json +10 -1
- package/DS1/0-face/translations/ja.json +10 -1
- package/DS1/0-face/translations/ko.json +10 -1
- package/DS1/0-face/translations/nb.json +10 -1
- package/DS1/0-face/translations/pt-BR.json +10 -1
- package/DS1/0-face/translations/pt.json +10 -1
- package/DS1/0-face/translations/sv.json +10 -1
- package/DS1/0-face/translations/zh.json +10 -1
- package/DS1/0-face/word-wrap.ts +113 -0
- package/DS1/1-root/card.css +47 -20
- package/DS1/1-root/carousel.css +7 -0
- package/DS1/1-root/cjk.css +1 -1
- package/DS1/1-root/component-tokens.css +3 -2
- package/DS1/1-root/context.css +44 -6
- package/DS1/1-root/controls.css +99 -8
- package/DS1/1-root/document.css +9 -1
- package/DS1/1-root/empty.css +46 -5
- package/DS1/1-root/figures.css +50 -3
- package/DS1/1-root/fonts.css +1 -1
- package/DS1/1-root/footer.css +147 -16
- package/DS1/1-root/foundation.ts +60 -0
- package/DS1/1-root/guide.css +35 -0
- package/DS1/1-root/header.css +30 -9
- package/DS1/1-root/library-tokens.ts +1 -2
- package/DS1/1-root/material.css +67 -0
- package/DS1/1-root/notice.css +10 -2
- package/DS1/1-root/one.css +14 -7
- package/DS1/1-root/palette.ts +3 -3
- package/DS1/1-root/progress.css +9 -1
- package/DS1/1-root/row.css +68 -2
- package/DS1/1-root/table.css +47 -4
- package/DS1/1-root/text.css +26 -0
- package/DS1/2-core/button-split.ts +10 -5
- package/DS1/2-core/chart/chart.css +71 -2
- package/DS1/2-core/chart/grid-chart.ts +2 -1
- package/DS1/2-core/ds-activity.ts +32 -0
- package/DS1/2-core/ds-app-chrome.ts +1 -0
- package/DS1/2-core/ds-avatar.ts +35 -6
- package/DS1/2-core/ds-badge.ts +8 -1
- package/DS1/2-core/ds-button.ts +7 -1
- package/DS1/2-core/ds-chart.ts +184 -49
- package/DS1/2-core/ds-cycle.ts +27 -186
- package/DS1/2-core/ds-device-bezel.ts +1 -0
- package/DS1/2-core/ds-empty.ts +6 -4
- package/DS1/2-core/ds-input.ts +23 -3
- package/DS1/2-core/ds-message.ts +22 -0
- package/DS1/2-core/ds-number.ts +349 -0
- package/DS1/2-core/ds-progress.ts +3 -0
- package/DS1/2-core/ds-radio.ts +3 -0
- package/DS1/2-core/ds-stat.ts +3 -0
- package/DS1/2-core/ds-switch.ts +5 -1
- package/DS1/2-core/ds-tag.ts +9 -2
- package/DS1/2-core/ds-text.ts +7 -0
- package/DS1/2-core/ds-token.ts +3 -0
- package/DS1/2-core/ds-tooltip.ts +17 -2
- package/DS1/2-core/ds-window.ts +1 -0
- package/DS1/2-core/generated/ds-icon-map.ts +47 -5
- package/DS1/2-core/generated/icons-extra.ts +24 -3
- package/DS1/2-core/generated/icons-immediate.ts +3 -3
- package/DS1/2-core/number-expression.ts +64 -0
- package/DS1/2-core/styles/ds-activity.css +16 -0
- package/DS1/2-core/styles/ds-badge.css +4 -1
- package/DS1/2-core/styles/ds-button-host.css +45 -12
- package/DS1/2-core/styles/ds-button-split.css +8 -0
- package/DS1/2-core/styles/ds-button.css +92 -19
- package/DS1/2-core/styles/ds-card.css +6 -0
- package/DS1/2-core/styles/ds-checkbox.css +20 -8
- package/DS1/2-core/styles/ds-image.css +2 -1
- package/DS1/2-core/styles/ds-input.css +37 -4
- package/DS1/2-core/styles/ds-number.css +127 -0
- package/DS1/2-core/styles/ds-radio.css +4 -1
- package/DS1/2-core/styles/ds-switch.css +34 -4
- package/DS1/2-core/styles/ds-tag.css +32 -5
- package/DS1/2-core/styles/ds-text.css +13 -4
- package/DS1/2-core/styles/ds-token.css +4 -1
- package/DS1/2-core/styles/ds-tooltip.css +13 -7
- package/DS1/3-unit/calendar-base.ts +5 -2
- package/DS1/3-unit/ds-calendar.ts +711 -37
- package/DS1/3-unit/ds-carousel.ts +13 -1
- package/DS1/3-unit/ds-context.ts +40 -2
- package/DS1/3-unit/ds-form.ts +45 -10
- package/DS1/3-unit/ds-list.ts +31 -3
- package/DS1/3-unit/ds-matrix.ts +3 -0
- package/DS1/3-unit/ds-menu.ts +9 -5
- package/DS1/3-unit/ds-row.ts +17 -2
- package/DS1/3-unit/ds-select.ts +1 -1
- package/DS1/3-unit/ds-sidebar.ts +18 -3
- package/DS1/3-unit/ds-table-of-contents.ts +166 -0
- package/DS1/3-unit/ds-tabs.ts +40 -2
- package/DS1/3-unit/styles/ds-calendar.css +356 -42
- package/DS1/3-unit/styles/ds-context.css +38 -0
- package/DS1/3-unit/styles/ds-list.css +26 -1
- package/DS1/3-unit/styles/ds-matrix.css +4 -1
- package/DS1/3-unit/styles/ds-row.css +39 -0
- package/DS1/3-unit/styles/ds-select.css +22 -12
- package/DS1/3-unit/styles/ds-sidebar.css +16 -2
- package/DS1/3-unit/styles/ds-table-of-contents.css +40 -0
- package/DS1/3-unit/styles/ds-tabs.css +95 -0
- package/DS1/4-page/ds-document.ts +3 -0
- package/DS1/4-page/ds-footer.ts +93 -18
- package/DS1/4-page/ds-header.ts +5 -1
- package/DS1/4-page/ds-overlay.ts +8 -3
- package/DS1/4-page/ds-page.ts +22 -1
- package/DS1/4-page/email.ts +7 -4
- package/DS1/4-page/styles/ds-container.css +0 -1
- package/DS1/4-page/styles/ds-overlay.css +7 -0
- package/DS1/4-page/styles/ds-page.css +10 -0
- package/DS1/5-visual-kit/app-chrome.ts +129 -0
- package/DS1/5-visual-kit/bezels.ts +394 -0
- package/DS1/5-visual-kit/browser-icons.LICENSE +53 -0
- package/DS1/5-visual-kit/browser-icons.ts +47 -0
- package/DS1/5-visual-kit/browser-styles.ts +53 -0
- package/DS1/5-visual-kit/device-bezel.ts +55 -0
- package/DS1/5-visual-kit/instagram-frame.ts +15 -0
- package/DS1/5-visual-kit/instagram.ts +41 -0
- package/DS1/5-visual-kit/mobile-chrome.ts +25 -0
- package/DS1/5-visual-kit/native-icon-paths.ts +145 -0
- package/DS1/5-visual-kit/window.ts +22 -0
- package/DS1/components.ts +1 -0
- package/DS1/index.ts +14 -1
- package/DS1/react/choice.ts +4 -2
- package/DS1/react/context.ts +11 -6
- package/DS1/react/empty.ts +2 -2
- package/DS1/react/footer.ts +5 -5
- package/DS1/react/header.ts +1 -1
- package/DS1/react/message.ts +4 -2
- package/DS1/react/number.ts +53 -0
- package/DS1/react/sidebar.ts +4 -2
- package/DS1/react/table-of-contents.ts +28 -0
- package/DS1/x-flag/LICENSE.md +26 -0
- package/DS1/x-flag/ac.svg +1 -0
- package/DS1/x-flag/ad.svg +1 -0
- package/DS1/x-flag/ae.svg +1 -0
- package/DS1/x-flag/af.svg +1 -0
- package/DS1/x-flag/ag.svg +1 -0
- package/DS1/x-flag/ai.svg +1 -0
- package/DS1/x-flag/al.svg +1 -0
- package/DS1/x-flag/am.svg +1 -0
- package/DS1/x-flag/ao.svg +1 -0
- package/DS1/x-flag/aq.svg +1 -0
- package/DS1/x-flag/ar.svg +1 -0
- package/DS1/x-flag/as.svg +1 -0
- package/DS1/x-flag/at.svg +1 -0
- package/DS1/x-flag/au.svg +1 -0
- package/DS1/x-flag/aw.svg +1 -0
- package/DS1/x-flag/ax.svg +1 -0
- package/DS1/x-flag/az.svg +1 -0
- package/DS1/x-flag/ba.svg +1 -0
- package/DS1/x-flag/bb.svg +1 -0
- package/DS1/x-flag/bd.svg +1 -0
- package/DS1/x-flag/be.svg +1 -0
- package/DS1/x-flag/bf.svg +1 -0
- package/DS1/x-flag/bg.svg +1 -0
- package/DS1/x-flag/bh.svg +1 -0
- package/DS1/x-flag/bi.svg +1 -0
- package/DS1/x-flag/bj.svg +1 -0
- package/DS1/x-flag/bl.svg +1 -0
- package/DS1/x-flag/bm.svg +1 -0
- package/DS1/x-flag/bn.svg +1 -0
- package/DS1/x-flag/bo.svg +1 -0
- package/DS1/x-flag/bq-bo.svg +1 -0
- package/DS1/x-flag/bq-sa.svg +1 -0
- package/DS1/x-flag/bq-se.svg +1 -0
- package/DS1/x-flag/bq.svg +1 -0
- package/DS1/x-flag/br.svg +1 -0
- package/DS1/x-flag/bs.svg +1 -0
- package/DS1/x-flag/bt.svg +1 -0
- package/DS1/x-flag/bv.svg +1 -0
- package/DS1/x-flag/bw.svg +1 -0
- package/DS1/x-flag/by.svg +1 -0
- package/DS1/x-flag/bz.svg +1 -0
- package/DS1/x-flag/ca.svg +1 -0
- package/DS1/x-flag/cc.svg +1 -0
- package/DS1/x-flag/cd.svg +1 -0
- package/DS1/x-flag/cf.svg +1 -0
- package/DS1/x-flag/cg.svg +1 -0
- package/DS1/x-flag/ch.svg +1 -0
- package/DS1/x-flag/ci.svg +1 -0
- package/DS1/x-flag/ck.svg +1 -0
- package/DS1/x-flag/cl.svg +1 -0
- package/DS1/x-flag/cm.svg +1 -0
- package/DS1/x-flag/cn.svg +1 -0
- package/DS1/x-flag/co.svg +1 -0
- package/DS1/x-flag/cr.svg +1 -0
- package/DS1/x-flag/cu.svg +1 -0
- package/DS1/x-flag/cv.svg +1 -0
- package/DS1/x-flag/cw.svg +1 -0
- package/DS1/x-flag/cx.svg +1 -0
- package/DS1/x-flag/cy.svg +1 -0
- package/DS1/x-flag/cz.svg +1 -0
- package/DS1/x-flag/de.svg +1 -0
- package/DS1/x-flag/dj.svg +1 -0
- package/DS1/x-flag/dk.svg +1 -0
- package/DS1/x-flag/dm.svg +1 -0
- package/DS1/x-flag/do.svg +1 -0
- package/DS1/x-flag/dz.svg +1 -0
- package/DS1/x-flag/ec.svg +1 -0
- package/DS1/x-flag/ee.svg +1 -0
- package/DS1/x-flag/eg.svg +1 -0
- package/DS1/x-flag/eh.svg +1 -0
- package/DS1/x-flag/er.svg +1 -0
- package/DS1/x-flag/es-ct.svg +1 -0
- package/DS1/x-flag/es.svg +1 -0
- package/DS1/x-flag/et.svg +1 -0
- package/DS1/x-flag/eu.svg +1 -0
- package/DS1/x-flag/fi.svg +1 -0
- package/DS1/x-flag/fj.svg +1 -0
- package/DS1/x-flag/fk.svg +1 -0
- package/DS1/x-flag/fm.svg +1 -0
- package/DS1/x-flag/fo.svg +1 -0
- package/DS1/x-flag/fr.svg +1 -0
- package/DS1/x-flag/ga.svg +1 -0
- package/DS1/x-flag/gb-eng.svg +1 -0
- package/DS1/x-flag/gb-nir.svg +1 -0
- package/DS1/x-flag/gb-sct.svg +1 -0
- package/DS1/x-flag/gb-wls.svg +1 -0
- package/DS1/x-flag/gb.svg +1 -0
- package/DS1/x-flag/gd.svg +1 -0
- package/DS1/x-flag/ge.svg +1 -0
- package/DS1/x-flag/gf.svg +1 -0
- package/DS1/x-flag/gg.svg +1 -0
- package/DS1/x-flag/gh.svg +1 -0
- package/DS1/x-flag/gi.svg +1 -0
- package/DS1/x-flag/gl.svg +1 -0
- package/DS1/x-flag/gm.svg +1 -0
- package/DS1/x-flag/gn.svg +1 -0
- package/DS1/x-flag/gp.svg +1 -0
- package/DS1/x-flag/gq.svg +1 -0
- package/DS1/x-flag/gr.svg +1 -0
- package/DS1/x-flag/gs.svg +1 -0
- package/DS1/x-flag/gt.svg +1 -0
- package/DS1/x-flag/gu.svg +1 -0
- package/DS1/x-flag/gw.svg +1 -0
- package/DS1/x-flag/gy.svg +1 -0
- package/DS1/x-flag/hk.svg +1 -0
- package/DS1/x-flag/hm.svg +1 -0
- package/DS1/x-flag/hn.svg +1 -0
- package/DS1/x-flag/hr.svg +1 -0
- package/DS1/x-flag/ht.svg +1 -0
- package/DS1/x-flag/hu.svg +1 -0
- package/DS1/x-flag/ic.svg +1 -0
- package/DS1/x-flag/id.svg +1 -0
- package/DS1/x-flag/ie.svg +1 -0
- package/DS1/x-flag/il.svg +1 -0
- package/DS1/x-flag/im.svg +1 -0
- package/DS1/x-flag/in.svg +1 -0
- package/DS1/x-flag/io.svg +1 -0
- package/DS1/x-flag/iq.svg +1 -0
- package/DS1/x-flag/ir.svg +1 -0
- package/DS1/x-flag/is.svg +1 -0
- package/DS1/x-flag/it.svg +1 -0
- package/DS1/x-flag/je.svg +1 -0
- package/DS1/x-flag/jm.svg +1 -0
- package/DS1/x-flag/jo.svg +1 -0
- package/DS1/x-flag/jp.svg +1 -0
- package/DS1/x-flag/ke.svg +1 -0
- package/DS1/x-flag/kg.svg +1 -0
- package/DS1/x-flag/kh.svg +1 -0
- package/DS1/x-flag/ki.svg +1 -0
- package/DS1/x-flag/km.svg +1 -0
- package/DS1/x-flag/kn.svg +1 -0
- package/DS1/x-flag/kp.svg +1 -0
- package/DS1/x-flag/kr.svg +1 -0
- package/DS1/x-flag/kw.svg +1 -0
- package/DS1/x-flag/ky.svg +1 -0
- package/DS1/x-flag/kz.svg +1 -0
- package/DS1/x-flag/la.svg +1 -0
- package/DS1/x-flag/lb.svg +1 -0
- package/DS1/x-flag/lc.svg +1 -0
- package/DS1/x-flag/li.svg +1 -0
- package/DS1/x-flag/lk.svg +1 -0
- package/DS1/x-flag/lr.svg +1 -0
- package/DS1/x-flag/ls.svg +1 -0
- package/DS1/x-flag/lt.svg +1 -0
- package/DS1/x-flag/lu.svg +1 -0
- package/DS1/x-flag/lv.svg +1 -0
- package/DS1/x-flag/ly.svg +1 -0
- package/DS1/x-flag/ma.svg +1 -0
- package/DS1/x-flag/mc.svg +1 -0
- package/DS1/x-flag/md.svg +1 -0
- package/DS1/x-flag/me.svg +1 -0
- package/DS1/x-flag/mf.svg +1 -0
- package/DS1/x-flag/mg.svg +1 -0
- package/DS1/x-flag/mh.svg +1 -0
- package/DS1/x-flag/mk.svg +1 -0
- package/DS1/x-flag/ml.svg +1 -0
- package/DS1/x-flag/mm.svg +1 -0
- package/DS1/x-flag/mn.svg +1 -0
- package/DS1/x-flag/mo.svg +1 -0
- package/DS1/x-flag/mp.svg +1 -0
- package/DS1/x-flag/mq.svg +1 -0
- package/DS1/x-flag/mr.svg +1 -0
- package/DS1/x-flag/ms.svg +1 -0
- package/DS1/x-flag/mt.svg +1 -0
- package/DS1/x-flag/mu.svg +1 -0
- package/DS1/x-flag/mv.svg +1 -0
- package/DS1/x-flag/mw.svg +1 -0
- package/DS1/x-flag/mx.svg +1 -0
- package/DS1/x-flag/my.svg +1 -0
- package/DS1/x-flag/mz.svg +1 -0
- package/DS1/x-flag/na.svg +1 -0
- package/DS1/x-flag/nc.svg +1 -0
- package/DS1/x-flag/ne.svg +1 -0
- package/DS1/x-flag/nf.svg +1 -0
- package/DS1/x-flag/ng.svg +1 -0
- package/DS1/x-flag/ni.svg +1 -0
- package/DS1/x-flag/nl.svg +1 -0
- package/DS1/x-flag/no.svg +1 -0
- package/DS1/x-flag/np.svg +1 -0
- package/DS1/x-flag/nr.svg +1 -0
- package/DS1/x-flag/nu.svg +1 -0
- package/DS1/x-flag/nz.svg +1 -0
- package/DS1/x-flag/om.svg +1 -0
- package/DS1/x-flag/pa.svg +1 -0
- package/DS1/x-flag/pe.svg +1 -0
- package/DS1/x-flag/pf.svg +1 -0
- package/DS1/x-flag/pg.svg +1 -0
- package/DS1/x-flag/ph.svg +1 -0
- package/DS1/x-flag/pk.svg +1 -0
- package/DS1/x-flag/pl.svg +1 -0
- package/DS1/x-flag/pm.svg +1 -0
- package/DS1/x-flag/pn.svg +1 -0
- package/DS1/x-flag/pr.svg +1 -0
- package/DS1/x-flag/ps.svg +1 -0
- package/DS1/x-flag/pt.svg +1 -0
- package/DS1/x-flag/pw.svg +1 -0
- package/DS1/x-flag/py.svg +1 -0
- package/DS1/x-flag/qa.svg +1 -0
- package/DS1/x-flag/re.svg +1 -0
- package/DS1/x-flag/ro.svg +1 -0
- package/DS1/x-flag/rs.svg +1 -0
- package/DS1/x-flag/ru.svg +1 -0
- package/DS1/x-flag/rw.svg +1 -0
- package/DS1/x-flag/sa.svg +1 -0
- package/DS1/x-flag/sb.svg +1 -0
- package/DS1/x-flag/sc.svg +1 -0
- package/DS1/x-flag/sd.svg +1 -0
- package/DS1/x-flag/se.svg +1 -0
- package/DS1/x-flag/sg.svg +1 -0
- package/DS1/x-flag/sh.svg +1 -0
- package/DS1/x-flag/si.svg +1 -0
- package/DS1/x-flag/sj.svg +1 -0
- package/DS1/x-flag/sk.svg +1 -0
- package/DS1/x-flag/sl.svg +1 -0
- package/DS1/x-flag/sm.svg +1 -0
- package/DS1/x-flag/sn.svg +1 -0
- package/DS1/x-flag/so.svg +1 -0
- package/DS1/x-flag/sr.svg +1 -0
- package/DS1/x-flag/ss.svg +1 -0
- package/DS1/x-flag/st.svg +1 -0
- package/DS1/x-flag/sv.svg +1 -0
- package/DS1/x-flag/sx.svg +1 -0
- package/DS1/x-flag/sy.svg +1 -0
- package/DS1/x-flag/sz.svg +1 -0
- package/DS1/x-flag/ta.svg +1 -0
- package/DS1/x-flag/tc.svg +1 -0
- package/DS1/x-flag/td.svg +1 -0
- package/DS1/x-flag/tf.svg +1 -0
- package/DS1/x-flag/tg.svg +1 -0
- package/DS1/x-flag/th.svg +1 -0
- package/DS1/x-flag/tj.svg +1 -0
- package/DS1/x-flag/tk.svg +1 -0
- package/DS1/x-flag/tl.svg +1 -0
- package/DS1/x-flag/tm.svg +1 -0
- package/DS1/x-flag/tn.svg +1 -0
- package/DS1/x-flag/to.svg +1 -0
- package/DS1/x-flag/tr.svg +1 -0
- package/DS1/x-flag/tt.svg +1 -0
- package/DS1/x-flag/tv.svg +1 -0
- package/DS1/x-flag/tw.svg +1 -0
- package/DS1/x-flag/tz.svg +1 -0
- package/DS1/x-flag/ua.svg +1 -0
- package/DS1/x-flag/ug.svg +1 -0
- package/DS1/x-flag/um.svg +1 -0
- package/DS1/x-flag/us.svg +1 -0
- package/DS1/x-flag/uy.svg +1 -0
- package/DS1/x-flag/uz.svg +1 -0
- package/DS1/x-flag/va.svg +1 -0
- package/DS1/x-flag/vc.svg +1 -0
- package/DS1/x-flag/ve.svg +1 -0
- package/DS1/x-flag/vg.svg +1 -0
- package/DS1/x-flag/vi.svg +1 -0
- package/DS1/x-flag/vn.svg +1 -0
- package/DS1/x-flag/vu.svg +1 -0
- package/DS1/x-flag/wf.svg +1 -0
- package/DS1/x-flag/ws.svg +1 -0
- package/DS1/x-flag/xk.svg +1 -0
- package/DS1/x-flag/ye.svg +1 -0
- package/DS1/x-flag/yt.svg +1 -0
- package/DS1/x-flag/za.svg +1 -0
- package/DS1/x-flag/zm.svg +1 -0
- package/DS1/x-flag/zw.svg +1 -0
- package/DS1/x-icon/android.svg +9 -0
- package/DS1/x-icon/arrange-check.svg +1 -1
- package/DS1/x-icon/arrange-page.svg +1 -1
- package/DS1/x-icon/chrome.svg +7 -0
- package/DS1/x-icon/edge-brand.svg +6 -0
- package/DS1/x-icon/firefox.svg +4 -0
- package/DS1/x-icon/health.svg +3 -0
- package/DS1/x-icon/left.svg +2 -3
- package/DS1/x-icon/linux.svg +1 -0
- package/DS1/x-icon/material.svg +1 -0
- package/DS1/x-icon/milestone-planned.svg +3 -0
- package/DS1/x-icon/milestone.svg +3 -0
- package/DS1/x-icon/more.svg +1 -5
- package/DS1/x-icon/network.svg +3 -0
- package/DS1/x-icon/opera.svg +4 -0
- package/DS1/x-icon/prediction.svg +3 -0
- package/DS1/x-icon/priority-high.svg +3 -0
- package/DS1/x-icon/priority-low.svg +3 -0
- package/DS1/x-icon/priority-medium.svg +3 -0
- package/DS1/x-icon/project.svg +3 -0
- package/DS1/x-icon/redo.svg +2 -2
- package/DS1/x-icon/repeat-small.svg +3 -0
- package/DS1/x-icon/safari.svg +4 -0
- package/DS1/x-icon/scaling.svg +3 -0
- package/DS1/x-icon/tabs.svg +4 -0
- package/DS1/x-icon/windows.svg +5 -0
- package/README.md +10 -6
- package/dist/0-face/button-label.d.ts +5 -0
- package/dist/0-face/button-label.d.ts.map +1 -0
- package/dist/0-face/button-label.js +31 -0
- package/dist/0-face/calendar.d.ts +1 -1
- package/dist/0-face/calendar.d.ts.map +1 -1
- package/dist/0-face/calendar.js +6 -3
- package/dist/0-face/carousel.d.ts +9 -0
- package/dist/0-face/carousel.d.ts.map +1 -1
- package/dist/0-face/carousel.js +80 -0
- package/dist/0-face/constraint-panel.d.ts +43 -0
- package/dist/0-face/constraint-panel.d.ts.map +1 -0
- package/dist/0-face/constraint-panel.js +429 -0
- package/dist/0-face/constraint-site.d.ts +72 -0
- package/dist/0-face/constraint-site.d.ts.map +1 -0
- package/dist/0-face/constraint-site.js +185 -0
- package/dist/0-face/constraints.d.ts +47 -0
- package/dist/0-face/constraints.d.ts.map +1 -0
- package/dist/0-face/constraints.js +247 -0
- package/dist/0-face/copy-text.js +1 -1
- package/dist/0-face/cut-fade.d.ts +112 -0
- package/dist/0-face/cut-fade.d.ts.map +1 -0
- package/dist/0-face/cut-fade.js +274 -0
- package/dist/0-face/define.d.ts.map +1 -1
- package/dist/0-face/define.js +24 -3
- package/dist/0-face/face-correction.d.ts +51 -0
- package/dist/0-face/face-correction.d.ts.map +1 -0
- package/dist/0-face/face-correction.js +80 -0
- package/dist/0-face/failures.d.ts +16 -0
- package/dist/0-face/failures.d.ts.map +1 -0
- package/dist/0-face/failures.js +21 -0
- package/dist/0-face/feedback-overlays.d.ts.map +1 -1
- package/dist/0-face/feedback-overlays.js +5 -3
- package/dist/0-face/feedback.d.ts +2 -0
- package/dist/0-face/feedback.d.ts.map +1 -1
- package/dist/0-face/feedback.js +1 -0
- package/dist/0-face/focus.d.ts +71 -0
- package/dist/0-face/focus.d.ts.map +1 -0
- package/dist/0-face/focus.js +196 -0
- package/dist/0-face/grid.d.ts +11 -1
- package/dist/0-face/grid.d.ts.map +1 -1
- package/dist/0-face/grid.js +90 -4
- package/dist/0-face/i18n.d.ts.map +1 -1
- package/dist/0-face/i18n.js +38 -16
- package/dist/0-face/layout-inspector.d.ts +5 -1
- package/dist/0-face/layout-inspector.d.ts.map +1 -1
- package/dist/0-face/layout-inspector.js +130 -104
- package/dist/0-face/preference-options.d.ts +4 -0
- package/dist/0-face/preference-options.d.ts.map +1 -1
- package/dist/0-face/scaling.d.ts +8 -1
- package/dist/0-face/scaling.d.ts.map +1 -1
- package/dist/0-face/scaling.js +19 -2
- package/dist/0-face/shape.d.ts +35 -0
- package/dist/0-face/shape.d.ts.map +1 -0
- package/dist/0-face/shape.js +23 -0
- package/dist/0-face/text-contrast.d.ts +22 -0
- package/dist/0-face/text-contrast.d.ts.map +1 -0
- package/dist/0-face/text-contrast.js +178 -0
- package/dist/0-face/theme-bootstrap.js +56 -0
- package/dist/0-face/toast-queue.d.ts +4 -0
- package/dist/0-face/toast-queue.d.ts.map +1 -1
- package/dist/0-face/toast-queue.js +4 -1
- package/dist/0-face/translations/da.json +10 -1
- package/dist/0-face/translations/de.json +10 -1
- package/dist/0-face/translations/en.json +10 -1
- package/dist/0-face/translations/es.json +10 -1
- package/dist/0-face/translations/fi.json +10 -1
- package/dist/0-face/translations/fr.json +10 -1
- package/dist/0-face/translations/is.json +10 -1
- package/dist/0-face/translations/it.json +10 -1
- package/dist/0-face/translations/ja.json +10 -1
- package/dist/0-face/translations/ko.json +10 -1
- package/dist/0-face/translations/nb.json +10 -1
- package/dist/0-face/translations/pt-BR.json +10 -1
- package/dist/0-face/translations/pt.json +10 -1
- package/dist/0-face/translations/sv.json +10 -1
- package/dist/0-face/translations/zh.json +10 -1
- package/dist/0-face/word-wrap.d.ts +6 -0
- package/dist/0-face/word-wrap.d.ts.map +1 -0
- package/dist/0-face/word-wrap.js +119 -0
- package/dist/1-root/foundation.d.ts +12 -0
- package/dist/1-root/foundation.d.ts.map +1 -0
- package/dist/1-root/foundation.js +59 -0
- package/dist/1-root/library-tokens.d.ts.map +1 -1
- package/dist/1-root/library-tokens.js +1 -2
- package/dist/1-root/palette.d.ts +2 -2
- package/dist/1-root/palette.d.ts.map +1 -1
- package/dist/1-root/palette.js +3 -3
- package/dist/2-core/button-split.d.ts +1 -0
- package/dist/2-core/button-split.d.ts.map +1 -1
- package/dist/2-core/button-split.js +9 -4
- package/dist/2-core/chart/grid-chart.d.ts +2 -0
- package/dist/2-core/chart/grid-chart.d.ts.map +1 -1
- package/dist/2-core/chart/grid-chart.js +2 -1
- package/dist/2-core/ds-activity.d.ts +25 -0
- package/dist/2-core/ds-activity.d.ts.map +1 -0
- package/dist/2-core/ds-activity.js +28 -0
- package/dist/2-core/ds-app-chrome.d.ts +2 -0
- package/dist/2-core/ds-app-chrome.d.ts.map +1 -0
- package/dist/2-core/ds-app-chrome.js +1 -0
- package/dist/2-core/ds-avatar.d.ts +7 -0
- package/dist/2-core/ds-avatar.d.ts.map +1 -1
- package/dist/2-core/ds-avatar.js +41 -6
- package/dist/2-core/ds-badge.d.ts +7 -1
- package/dist/2-core/ds-badge.d.ts.map +1 -1
- package/dist/2-core/ds-badge.js +8 -1
- package/dist/2-core/ds-button.d.ts +12 -0
- package/dist/2-core/ds-button.d.ts.map +1 -1
- package/dist/2-core/ds-button.js +4 -0
- package/dist/2-core/ds-chart.d.ts +28 -3
- package/dist/2-core/ds-chart.d.ts.map +1 -1
- package/dist/2-core/ds-chart.js +110 -130
- package/dist/2-core/ds-cycle.d.ts +2 -2
- package/dist/2-core/ds-cycle.d.ts.map +1 -1
- package/dist/2-core/ds-cycle.js +36 -171
- package/dist/2-core/ds-device-bezel.d.ts +2 -0
- package/dist/2-core/ds-device-bezel.d.ts.map +1 -0
- package/dist/2-core/ds-device-bezel.js +1 -0
- package/dist/2-core/ds-empty.d.ts +2 -2
- package/dist/2-core/ds-empty.d.ts.map +1 -1
- package/dist/2-core/ds-empty.js +6 -4
- package/dist/2-core/ds-input.d.ts +7 -0
- package/dist/2-core/ds-input.d.ts.map +1 -1
- package/dist/2-core/ds-input.js +23 -3
- package/dist/2-core/ds-message.d.ts +11 -0
- package/dist/2-core/ds-message.d.ts.map +1 -1
- package/dist/2-core/ds-message.js +18 -0
- package/dist/2-core/ds-number.d.ts +86 -0
- package/dist/2-core/ds-number.d.ts.map +1 -0
- package/dist/2-core/ds-number.js +326 -0
- package/dist/2-core/ds-progress.d.ts +3 -0
- package/dist/2-core/ds-progress.d.ts.map +1 -1
- package/dist/2-core/ds-progress.js +3 -0
- package/dist/2-core/ds-radio.d.ts +3 -0
- package/dist/2-core/ds-radio.d.ts.map +1 -1
- package/dist/2-core/ds-radio.js +10 -1
- package/dist/2-core/ds-stat.d.ts +3 -0
- package/dist/2-core/ds-stat.d.ts.map +1 -1
- package/dist/2-core/ds-stat.js +3 -0
- package/dist/2-core/ds-switch.d.ts +14 -1
- package/dist/2-core/ds-switch.d.ts.map +1 -1
- package/dist/2-core/ds-switch.js +3 -1
- package/dist/2-core/ds-tag.d.ts +8 -1
- package/dist/2-core/ds-tag.d.ts.map +1 -1
- package/dist/2-core/ds-tag.js +12 -2
- package/dist/2-core/ds-text.d.ts +7 -0
- package/dist/2-core/ds-text.d.ts.map +1 -1
- package/dist/2-core/ds-text.js +7 -0
- package/dist/2-core/ds-token.d.ts +3 -0
- package/dist/2-core/ds-token.d.ts.map +1 -1
- package/dist/2-core/ds-token.js +3 -0
- package/dist/2-core/ds-tooltip.d.ts.map +1 -1
- package/dist/2-core/ds-tooltip.js +23 -2
- package/dist/2-core/ds-window.d.ts +2 -0
- package/dist/2-core/ds-window.d.ts.map +1 -0
- package/dist/2-core/ds-window.js +1 -0
- package/dist/2-core/generated/ds-icon-map.d.ts +27 -6
- package/dist/2-core/generated/ds-icon-map.d.ts.map +1 -1
- package/dist/2-core/generated/ds-icon-map.js +47 -5
- package/dist/2-core/generated/icons-extra.d.ts.map +1 -1
- package/dist/2-core/generated/icons-extra.js +24 -3
- package/dist/2-core/generated/icons-immediate.d.ts +1 -1
- package/dist/2-core/generated/icons-immediate.d.ts.map +1 -1
- package/dist/2-core/generated/icons-immediate.js +3 -3
- package/dist/2-core/number-expression.d.ts +12 -0
- package/dist/2-core/number-expression.d.ts.map +1 -0
- package/dist/2-core/number-expression.js +82 -0
- package/dist/3-unit/calendar-base.d.ts +5 -0
- package/dist/3-unit/calendar-base.d.ts.map +1 -1
- package/dist/3-unit/calendar-base.js +3 -2
- package/dist/3-unit/ds-calendar.d.ts +197 -4
- package/dist/3-unit/ds-calendar.d.ts.map +1 -1
- package/dist/3-unit/ds-calendar.js +687 -45
- package/dist/3-unit/ds-carousel.d.ts +3 -0
- package/dist/3-unit/ds-carousel.d.ts.map +1 -1
- package/dist/3-unit/ds-carousel.js +13 -1
- package/dist/3-unit/ds-context.d.ts +18 -1
- package/dist/3-unit/ds-context.d.ts.map +1 -1
- package/dist/3-unit/ds-context.js +37 -1
- package/dist/3-unit/ds-form.d.ts +9 -0
- package/dist/3-unit/ds-form.d.ts.map +1 -1
- package/dist/3-unit/ds-form.js +50 -10
- package/dist/3-unit/ds-list.d.ts +20 -1
- package/dist/3-unit/ds-list.d.ts.map +1 -1
- package/dist/3-unit/ds-list.js +31 -3
- package/dist/3-unit/ds-matrix.d.ts +3 -0
- package/dist/3-unit/ds-matrix.d.ts.map +1 -1
- package/dist/3-unit/ds-matrix.js +3 -0
- package/dist/3-unit/ds-menu.d.ts.map +1 -1
- package/dist/3-unit/ds-menu.js +17 -1
- package/dist/3-unit/ds-row.d.ts +13 -0
- package/dist/3-unit/ds-row.d.ts.map +1 -1
- package/dist/3-unit/ds-row.js +15 -2
- package/dist/3-unit/ds-select.js +1 -1
- package/dist/3-unit/ds-sidebar.d.ts +17 -0
- package/dist/3-unit/ds-sidebar.d.ts.map +1 -1
- package/dist/3-unit/ds-sidebar.js +14 -3
- package/dist/3-unit/ds-table-of-contents.d.ts +68 -0
- package/dist/3-unit/ds-table-of-contents.d.ts.map +1 -0
- package/dist/3-unit/ds-table-of-contents.js +190 -0
- package/dist/3-unit/ds-tabs.d.ts +32 -1
- package/dist/3-unit/ds-tabs.d.ts.map +1 -1
- package/dist/3-unit/ds-tabs.js +39 -1
- package/dist/4-page/ds-document.d.ts +3 -0
- package/dist/4-page/ds-document.d.ts.map +1 -1
- package/dist/4-page/ds-document.js +3 -0
- package/dist/4-page/ds-footer.d.ts +47 -7
- package/dist/4-page/ds-footer.d.ts.map +1 -1
- package/dist/4-page/ds-footer.js +58 -14
- package/dist/4-page/ds-header.d.ts +6 -0
- package/dist/4-page/ds-header.d.ts.map +1 -1
- package/dist/4-page/ds-header.js +4 -1
- package/dist/4-page/ds-overlay.d.ts +2 -2
- package/dist/4-page/ds-overlay.d.ts.map +1 -1
- package/dist/4-page/ds-overlay.js +8 -3
- package/dist/4-page/ds-page.d.ts +12 -0
- package/dist/4-page/ds-page.d.ts.map +1 -1
- package/dist/4-page/ds-page.js +19 -1
- package/dist/4-page/email.d.ts +2 -0
- package/dist/4-page/email.d.ts.map +1 -1
- package/dist/4-page/email.js +5 -4
- package/dist/5-visual-kit/app-chrome.d.ts +98 -0
- package/dist/5-visual-kit/app-chrome.d.ts.map +1 -0
- package/dist/5-visual-kit/app-chrome.js +119 -0
- package/dist/5-visual-kit/bezels.d.ts +30 -0
- package/dist/5-visual-kit/bezels.d.ts.map +1 -0
- package/dist/5-visual-kit/bezels.js +388 -0
- package/dist/5-visual-kit/browser-icons.d.ts +5 -0
- package/dist/5-visual-kit/browser-icons.d.ts.map +1 -0
- package/dist/5-visual-kit/browser-icons.js +51 -0
- package/dist/5-visual-kit/browser-styles.d.ts +3 -0
- package/dist/5-visual-kit/browser-styles.d.ts.map +1 -0
- package/dist/5-visual-kit/browser-styles.js +52 -0
- package/dist/5-visual-kit/device-bezel.d.ts +84 -0
- package/dist/5-visual-kit/device-bezel.d.ts.map +1 -0
- package/dist/5-visual-kit/device-bezel.js +56 -0
- package/dist/5-visual-kit/instagram-frame.d.ts +8 -0
- package/dist/5-visual-kit/instagram-frame.d.ts.map +1 -0
- package/dist/5-visual-kit/instagram-frame.js +13 -0
- package/dist/5-visual-kit/instagram.d.ts +18 -0
- package/dist/5-visual-kit/instagram.d.ts.map +1 -0
- package/dist/5-visual-kit/instagram.js +39 -0
- package/dist/5-visual-kit/mobile-chrome.d.ts +4 -0
- package/dist/5-visual-kit/mobile-chrome.d.ts.map +1 -0
- package/dist/5-visual-kit/mobile-chrome.js +24 -0
- package/dist/5-visual-kit/native-icon-paths.d.ts +146 -0
- package/dist/5-visual-kit/native-icon-paths.d.ts.map +1 -0
- package/dist/5-visual-kit/native-icon-paths.js +145 -0
- package/dist/5-visual-kit/window.d.ts +51 -0
- package/dist/5-visual-kit/window.d.ts.map +1 -0
- package/dist/5-visual-kit/window.js +20 -0
- package/dist/browser-icons-BFbS1tIx.js +56 -0
- package/dist/browser-icons-BFbS1tIx.js.map +1 -0
- package/dist/browser-icons-CT8qU77Z.js +48 -0
- package/dist/browser-icons-CT8qU77Z.js.map +1 -0
- package/dist/components.d.ts +1 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +1 -0
- package/dist/design-system-1.bundle.js +5505 -2068
- package/dist/design-system-1.bundle.js.map +1 -1
- package/dist/design-system-1.bundle.min.js +7026 -4628
- package/dist/design-system-1.bundle.min.js.map +1 -1
- package/dist/design-system-1.css +1 -1
- package/dist/feedback.js +197 -167
- package/dist/feedback.js.map +1 -1
- package/dist/{icons-extra-CRxxWFjX.js → icons-extra-BMPvmQPI.js} +25 -4
- package/dist/icons-extra-BMPvmQPI.js.map +1 -0
- package/dist/{icons-extra-H5pqCM_R.js → icons-extra-BfYOw-cR.js} +83 -5
- package/dist/icons-extra-BfYOw-cR.js.map +1 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/instagram-CKofs55A.js +50 -0
- package/dist/instagram-CKofs55A.js.map +1 -0
- package/dist/instagram-CcYf5oiM.js +48 -0
- package/dist/instagram-CcYf5oiM.js.map +1 -0
- package/dist/lit-Ce_uWYM4.js +612 -0
- package/dist/lit-Ce_uWYM4.js.map +1 -0
- package/dist/lit-DGUVm1Ce.js +557 -0
- package/dist/lit-DGUVm1Ce.js.map +1 -0
- package/dist/native-icon-paths-CB9evXBM.js +93 -0
- package/dist/native-icon-paths-CB9evXBM.js.map +1 -0
- package/dist/native-icon-paths-zay-3g_n.js +150 -0
- package/dist/native-icon-paths-zay-3g_n.js.map +1 -0
- package/dist/react/avatar.d.ts +1 -1
- package/dist/react/choice.d.ts +4 -0
- package/dist/react/choice.d.ts.map +1 -1
- package/dist/react/choice.js +2 -2
- package/dist/react/context.d.ts +19 -4
- package/dist/react/context.d.ts.map +1 -1
- package/dist/react/context.js +4 -4
- package/dist/react/empty.d.ts +2 -2
- package/dist/react/empty.d.ts.map +1 -1
- package/dist/react/empty.js +1 -1
- package/dist/react/footer.d.ts +5 -5
- package/dist/react/footer.d.ts.map +1 -1
- package/dist/react/footer.js +2 -2
- package/dist/react/header.d.ts +2 -2
- package/dist/react/header.d.ts.map +1 -1
- package/dist/react/message.d.ts +4 -0
- package/dist/react/message.d.ts.map +1 -1
- package/dist/react/message.js +2 -2
- package/dist/react/number.d.ts +53 -0
- package/dist/react/number.d.ts.map +1 -0
- package/dist/react/number.js +25 -0
- package/dist/react/page.d.ts +1 -1
- package/dist/react/sidebar.d.ts +4 -0
- package/dist/react/sidebar.d.ts.map +1 -1
- package/dist/react/sidebar.js +2 -2
- package/dist/react/table-of-contents.d.ts +19 -0
- package/dist/react/table-of-contents.d.ts.map +1 -0
- package/dist/react/table-of-contents.js +28 -0
- package/dist/{shared-words-CdMDVtXx.js → shared-words-C5cjxMjZ.js} +151 -16
- package/dist/shared-words-C5cjxMjZ.js.map +1 -0
- package/dist/{shared-words-BtRee8xR.js → shared-words-Cdm7xd-_.js} +163 -28
- package/dist/shared-words-Cdm7xd-_.js.map +1 -0
- package/package.json +24 -13
- package/DS1/1-root/one.semantic.css +0 -735
- package/DS1/3-unit/ds-calendar-large.ts +0 -353
- package/DS1/3-unit/styles/ds-calendar-large.css +0 -178
- package/dist/3-unit/ds-calendar-large.d.ts +0 -142
- package/dist/3-unit/ds-calendar-large.d.ts.map +0 -1
- package/dist/3-unit/ds-calendar-large.js +0 -308
- package/dist/icons-extra-CRxxWFjX.js.map +0 -1
- package/dist/icons-extra-H5pqCM_R.js.map +0 -1
- package/dist/shared-words-BtRee8xR.js.map +0 -1
- package/dist/shared-words-CdMDVtXx.js.map +0 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { LitElement, html, nothing, unsafeCSS, type PropertyValues } from "lit";
|
|
10
10
|
import { getText } from "../0-face/i18n";
|
|
11
11
|
import { define } from "../0-face/define";
|
|
12
|
-
import { COPY, autoplayInterval, bleedOf, driveCarousel, nearestSlide, prefersReducedMotion, scrollToSlide, type CarouselDrive } from "../0-face/carousel";
|
|
12
|
+
import { COPY, autoplayInterval, bleedOf, dragTrack, driveCarousel, nearestSlide, prefersReducedMotion, scrollToSlide, type CarouselDrive } from "../0-face/carousel";
|
|
13
13
|
import "../2-core/ds-icon";
|
|
14
14
|
import "../2-core/ds-progress";
|
|
15
15
|
import type { ProgressSelectDetail } from "../2-core/ds-progress";
|
|
@@ -113,6 +113,8 @@ export class Carousel extends LitElement {
|
|
|
113
113
|
declare paused: boolean;
|
|
114
114
|
/** The strip's drive: the bleed's measures, the loop's copies and autoplay. */
|
|
115
115
|
private drive: CarouselDrive | null = null;
|
|
116
|
+
/** Stops the strip's drag (dragTrack); started with the track, again when the element comes back to a page. */
|
|
117
|
+
private undrag: (() => void) | undefined;
|
|
116
118
|
|
|
117
119
|
/** Attributes this element wrote, so what the page wrote is left alone. */
|
|
118
120
|
private readonly own = new Map<Element, Set<string>>();
|
|
@@ -165,8 +167,14 @@ export class Carousel extends LitElement {
|
|
|
165
167
|
return Math.max(0, Math.min(this.count - 1, current));
|
|
166
168
|
}
|
|
167
169
|
|
|
170
|
+
private startDrag() {
|
|
171
|
+
const track = this.track;
|
|
172
|
+
if (track && !this.undrag) this.undrag = dragTrack(track, () => { if (!this.loop) this.move(nearestSlide(track, this.slides, this.index)); });
|
|
173
|
+
}
|
|
174
|
+
|
|
168
175
|
connectedCallback() {
|
|
169
176
|
super.connectedCallback();
|
|
177
|
+
if (this.hasUpdated) this.startDrag();
|
|
170
178
|
window.addEventListener("language-changed", this.relabel);
|
|
171
179
|
window.addEventListener("translations-loaded", this.relabel);
|
|
172
180
|
}
|
|
@@ -178,6 +186,8 @@ export class Carousel extends LitElement {
|
|
|
178
186
|
clearTimeout(this.settle);
|
|
179
187
|
this.drive?.stop();
|
|
180
188
|
this.drive = null;
|
|
189
|
+
this.undrag?.();
|
|
190
|
+
this.undrag = undefined;
|
|
181
191
|
super.disconnectedCallback();
|
|
182
192
|
}
|
|
183
193
|
|
|
@@ -225,6 +235,8 @@ export class Carousel extends LitElement {
|
|
|
225
235
|
protected firstUpdated() {
|
|
226
236
|
// The strip's drive starts once, from the options the element was given.
|
|
227
237
|
const track = this.track;
|
|
238
|
+
// A mouse drags the strip, and a press that ends a drag or a swipe chooses nothing (dragTrack).
|
|
239
|
+
this.startDrag();
|
|
228
240
|
const bleed = bleedOf(this.bleed);
|
|
229
241
|
if (track && (bleed !== "none" || this.loop || this.every > 0)) {
|
|
230
242
|
this.drive = driveCarousel(this, track, this, { bleed, loop: this.loop, autoplay: this.every });
|
package/DS1/3-unit/ds-context.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { unsafeCSS, type PropertyValues } from "lit";
|
|
|
2
2
|
import { define } from "../0-face/define";
|
|
3
3
|
import menuStyles from "./styles/ds-menu.css?inline";
|
|
4
4
|
import styles from "./styles/ds-context.css?inline";
|
|
5
|
-
import { Menu, type MenuCloseReason } from "./ds-menu";
|
|
5
|
+
import { Menu, type MenuAnchor, type MenuCloseReason } from "./ds-menu";
|
|
6
6
|
|
|
7
7
|
const ROW = '[role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]';
|
|
8
8
|
/** A refused change shows on its row this long, as Ezo shows it. */
|
|
@@ -25,20 +25,31 @@ const REFUSED = 1400;
|
|
|
25
25
|
* says `data-keep-open` or its click was prevented. `pending` holds every row
|
|
26
26
|
* and the menu open while an answer is awaited; `refuse(row)` shows a refused
|
|
27
27
|
* change on its row.
|
|
28
|
+
*
|
|
29
|
+
* `bar` lays the same rows side by side, the context bar over what is
|
|
30
|
+
* selected: one row high, the cells a pixel apart and groups two, a cell
|
|
31
|
+
* holding only an icon one square, a cell with words 4px in. It stands half a
|
|
32
|
+
* square above its anchor (below when there is no room), its start at the
|
|
33
|
+
* anchor's, and opens without taking the focus, so the writing keeps the
|
|
34
|
+
* caret: `openOver(rect)`. ← and → move along it.
|
|
28
35
|
*/
|
|
29
36
|
export class Context extends Menu {
|
|
30
37
|
static properties = {
|
|
31
38
|
...Menu.properties,
|
|
32
39
|
pending: { type: Boolean, reflect: true },
|
|
40
|
+
bar: { type: Boolean, reflect: true },
|
|
33
41
|
};
|
|
34
42
|
static styles = [unsafeCSS(menuStyles), unsafeCSS(styles)];
|
|
35
43
|
/** Hold every row and keep the menu open while a chosen change is awaited. */
|
|
36
44
|
declare pending: boolean;
|
|
45
|
+
/** The context bar: the rows side by side, over what is selected. */
|
|
46
|
+
declare bar: boolean;
|
|
37
47
|
private quietObserver = new MutationObserver(() => this.quietSeparators());
|
|
38
48
|
|
|
39
49
|
constructor() {
|
|
40
50
|
super();
|
|
41
51
|
this.pending = false;
|
|
52
|
+
this.bar = false;
|
|
42
53
|
this.triggerMode = "context";
|
|
43
54
|
this.floating = true;
|
|
44
55
|
this.closesOnChoice = true;
|
|
@@ -57,11 +68,23 @@ export class Context extends Menu {
|
|
|
57
68
|
// Always a context menu, always floating.
|
|
58
69
|
this.triggerMode = "context";
|
|
59
70
|
this.floating = true;
|
|
60
|
-
|
|
71
|
+
// A menu hugs its words in whole squares; a bar is as long as its cells.
|
|
72
|
+
this.toggleAttribute("data-ds-hug", !this.bar);
|
|
73
|
+
if (this.bar) {
|
|
74
|
+
this.setAttribute("aria-orientation", "horizontal");
|
|
75
|
+
this.placement = "top";
|
|
76
|
+
// The writing under a bar keeps the caret; the page moves the focus in with a key of its own.
|
|
77
|
+
this.focusOnOpen = false;
|
|
78
|
+
} else if (changed.has("bar")) {
|
|
79
|
+
this.removeAttribute("aria-orientation");
|
|
80
|
+
this.placement = "bottom";
|
|
81
|
+
this.focusOnOpen = true;
|
|
82
|
+
}
|
|
61
83
|
super.willUpdate(changed);
|
|
62
84
|
}
|
|
63
85
|
updated() {
|
|
64
86
|
super.updated();
|
|
87
|
+
this.markIcons();
|
|
65
88
|
// Pending holds the rows that were free, and frees only those again.
|
|
66
89
|
for (const row of this.querySelectorAll<HTMLElement>(ROW)) {
|
|
67
90
|
if (this.pending && row.getAttribute("aria-disabled") !== "true") { row.setAttribute("aria-disabled", "true"); row.dataset.dsContextHeld = ""; }
|
|
@@ -84,8 +107,23 @@ export class Context extends Menu {
|
|
|
84
107
|
setTimeout(() => row.removeAttribute("data-ds-refused"), REFUSED);
|
|
85
108
|
}
|
|
86
109
|
|
|
110
|
+
/** Open the bar over what is selected (a rectangle, or an element), keeping the focus where it is. */
|
|
111
|
+
openOver(anchor: MenuAnchor) {
|
|
112
|
+
this.anchor = anchor;
|
|
113
|
+
this.open = true;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** In a bar, a cell holding only an icon is one square. */
|
|
117
|
+
private markIcons() {
|
|
118
|
+
for (const row of this.querySelectorAll<HTMLElement>(ROW)) {
|
|
119
|
+
if (row.closest("ds-context") !== this) continue;
|
|
120
|
+
row.toggleAttribute("data-ds-context-icon", this.bar && !(row.textContent ?? "").trim() && !!row.querySelector("ds-icon, svg, img"));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
87
124
|
/** Groups without rows leave no gap: a separator first, last or after another is quiet. */
|
|
88
125
|
private quietSeparators() {
|
|
126
|
+
this.markIcons();
|
|
89
127
|
let previousWasGap = true;
|
|
90
128
|
const children = [...this.children] as HTMLElement[];
|
|
91
129
|
const visible = children.filter(child => !child.hidden);
|
package/DS1/3-unit/ds-form.ts
CHANGED
|
@@ -12,6 +12,9 @@ export interface FormValidationResult {
|
|
|
12
12
|
errors: { [key: string]: string };
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/** Inputs Enter does not submit from: it presses or toggles them instead. */
|
|
16
|
+
const IMPLICIT_SUBMIT_SKIPS = new Set(["button", "submit", "reset", "image", "checkbox", "radio", "file", "color", "range"]);
|
|
17
|
+
|
|
15
18
|
export class Form extends LitElement {
|
|
16
19
|
static properties = {
|
|
17
20
|
action: { type: String },
|
|
@@ -275,17 +278,50 @@ export class Form extends LitElement {
|
|
|
275
278
|
void this.submit();
|
|
276
279
|
}
|
|
277
280
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (target.tagName.toLowerCase() !== "textarea") {
|
|
283
|
-
e.preventDefault();
|
|
284
|
-
void this.submit();
|
|
285
|
-
}
|
|
286
|
-
}
|
|
281
|
+
connectedCallback(): void {
|
|
282
|
+
super.connectedCallback();
|
|
283
|
+
this.addEventListener("click", this._handleButtonClick);
|
|
284
|
+
this.addEventListener("keydown", this._handleKeydown);
|
|
287
285
|
}
|
|
288
286
|
|
|
287
|
+
disconnectedCallback(): void {
|
|
288
|
+
this.removeEventListener("click", this._handleButtonClick);
|
|
289
|
+
this.removeEventListener("keydown", this._handleKeydown);
|
|
290
|
+
super.disconnectedCallback();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* The form is drawn in this element's shadow, so a submit or reset button
|
|
295
|
+
* put inside it belongs to no form of its own. Its click does what it would
|
|
296
|
+
* in a form: a native button (bare or in `ds-button control="slotted"`), or
|
|
297
|
+
* `<ds-button type="submit">`. A button in a real <form> is left to that form.
|
|
298
|
+
*/
|
|
299
|
+
private _handleButtonClick = (e: Event): void => {
|
|
300
|
+
if (e.defaultPrevented) return;
|
|
301
|
+
const control = (e.target as Element | null)?.closest?.("button, input, ds-button[type]");
|
|
302
|
+
if (!control || !this.contains(control)) return;
|
|
303
|
+
let type: string | null;
|
|
304
|
+
if (control instanceof HTMLButtonElement || control instanceof HTMLInputElement) {
|
|
305
|
+
if (control.form || control.disabled) return;
|
|
306
|
+
type = control.type;
|
|
307
|
+
} else {
|
|
308
|
+
if (control.hasAttribute("disabled") || control.hasAttribute("href")) return;
|
|
309
|
+
type = control.getAttribute("type");
|
|
310
|
+
}
|
|
311
|
+
if (type === "submit") void this.submit();
|
|
312
|
+
else if (type === "reset") this.reset();
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
private _handleKeydown = (e: KeyboardEvent): void => {
|
|
316
|
+
if (e.key !== "Enter" || e.shiftKey || e.defaultPrevented) return;
|
|
317
|
+
// Enter submits from a field, as in a form: on a button it presses that
|
|
318
|
+
// button, and in a textarea (a multiline ds-input's too) it starts a line.
|
|
319
|
+
const origin = e.composedPath()[0];
|
|
320
|
+
if (!(origin instanceof HTMLInputElement) || origin.form || IMPLICIT_SUBMIT_SKIPS.has(origin.type)) return;
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
void this.submit();
|
|
323
|
+
};
|
|
324
|
+
|
|
289
325
|
render() {
|
|
290
326
|
return html`
|
|
291
327
|
<form
|
|
@@ -295,7 +331,6 @@ export class Form extends LitElement {
|
|
|
295
331
|
?novalidate=${this.novalidate}
|
|
296
332
|
autocomplete=${this.autocomplete}
|
|
297
333
|
@submit=${this._handleSubmit}
|
|
298
|
-
@keydown=${this._handleKeydown}
|
|
299
334
|
>
|
|
300
335
|
<slot></slot>
|
|
301
336
|
</form>
|
package/DS1/3-unit/ds-list.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { LitElement, html, unsafeCSS } from "lit";
|
|
1
|
+
import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
2
2
|
import styles from "./styles/ds-list.css?inline";
|
|
3
3
|
import { define } from "../0-face/define";
|
|
4
|
+
import { CutFades } from "../0-face/cut-fade";
|
|
4
5
|
|
|
5
6
|
/** Children that are never items of the list. */
|
|
6
7
|
const NOT_ITEMS = new Set(["template", "script", "style", "slot"]);
|
|
@@ -15,21 +16,34 @@ const CONTROLS = new Set(["a", "button", "input", "select", "textarea", "summary
|
|
|
15
16
|
* A link, button or other control directly inside keeps its own role: wrap it
|
|
16
17
|
* in a row (or another element) to make it an item.
|
|
17
18
|
*
|
|
19
|
+
* `heading` names the group on the square above its rows (a day, a month),
|
|
20
|
+
* the words in the muted ink: the list takes it as its accessible name, so
|
|
21
|
+
* the drawn words are hidden from assistive technology and a page that
|
|
22
|
+
* writes its own `aria-label` keeps it.
|
|
23
|
+
*
|
|
18
24
|
* @element ds-list
|
|
19
25
|
* @attr columns - Lay the items out in this many equal columns.
|
|
26
|
+
* @attr heading - The group's name, drawn on the square above the rows and given to the list as its name.
|
|
27
|
+
* @csspart heading - The heading's line.
|
|
20
28
|
*/
|
|
21
29
|
export class List extends LitElement {
|
|
22
30
|
static properties = {
|
|
23
31
|
columns: { type: Number, reflect: true },
|
|
32
|
+
heading: { type: String, reflect: true },
|
|
24
33
|
};
|
|
25
34
|
|
|
26
35
|
declare columns: number | undefined;
|
|
36
|
+
declare heading: string | undefined;
|
|
27
37
|
|
|
28
38
|
static styles = unsafeCSS(styles);
|
|
39
|
+
/** Words cut short fade over their last square, never an ellipsis: marks them `data-cut="end"` while they do not fit. */
|
|
40
|
+
protected readonly cuts = new CutFades(this, { selector: ".heading" });
|
|
29
41
|
|
|
30
42
|
/** The items this element gave a role, so roles the page wrote are left alone. */
|
|
31
43
|
private ownItems = new Set<Element>();
|
|
32
44
|
private ownRole = false;
|
|
45
|
+
/** Whether the list's `aria-label` is its heading, so the page's own name is never replaced. */
|
|
46
|
+
private ownLabel = false;
|
|
33
47
|
|
|
34
48
|
connectedCallback(): void {
|
|
35
49
|
super.connectedCallback();
|
|
@@ -64,13 +78,27 @@ export class List extends LitElement {
|
|
|
64
78
|
this.syncItems();
|
|
65
79
|
}
|
|
66
80
|
|
|
67
|
-
updated(): void {
|
|
81
|
+
updated(changed: Map<string, unknown>): void {
|
|
68
82
|
if (typeof this.columns === "number" && Number.isInteger(this.columns) && this.columns > 0) this.style.setProperty("--ds-list-columns", String(this.columns));
|
|
69
83
|
else this.style.removeProperty("--ds-list-columns");
|
|
84
|
+
if (changed.has("heading")) this.nameByHeading();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** The heading names the list, unless the page wrote a name of its own. */
|
|
88
|
+
private nameByHeading() {
|
|
89
|
+
const heading = this.heading?.trim();
|
|
90
|
+
if (heading && (this.ownLabel || !this.hasAttribute("aria-label"))) {
|
|
91
|
+
this.setAttribute("aria-label", heading);
|
|
92
|
+
this.ownLabel = true;
|
|
93
|
+
} else if (!heading && this.ownLabel) {
|
|
94
|
+
this.removeAttribute("aria-label");
|
|
95
|
+
this.ownLabel = false;
|
|
96
|
+
}
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
render() {
|
|
73
|
-
|
|
100
|
+
const heading = this.heading?.trim();
|
|
101
|
+
return html`${heading ? html`<span class="heading" part="heading" aria-hidden="true">${heading}</span>` : nothing}<slot @slotchange=${this.syncItems}></slot>`;
|
|
74
102
|
}
|
|
75
103
|
}
|
|
76
104
|
|
package/DS1/3-unit/ds-matrix.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { LitElement, html, nothing, unsafeCSS, type PropertyValues } from "lit";
|
|
9
9
|
import { define } from "../0-face/define";
|
|
10
|
+
import { CutFades } from "../0-face/cut-fade";
|
|
10
11
|
import { getText } from "../0-face/i18n";
|
|
11
12
|
import metrics from "../1-root/component-metrics.css?inline";
|
|
12
13
|
import styles from "./styles/ds-matrix.css?inline";
|
|
@@ -107,6 +108,8 @@ export class Matrix extends LitElement {
|
|
|
107
108
|
};
|
|
108
109
|
|
|
109
110
|
static styles = [unsafeCSS(metrics), unsafeCSS(styles)];
|
|
111
|
+
/** Words cut short fade over their last square, never an ellipsis: marks them `data-cut="end"` while they do not fit. */
|
|
112
|
+
protected readonly cuts = new CutFades(this, { selector: ".name" });
|
|
110
113
|
|
|
111
114
|
declare rows: MatrixAxis[];
|
|
112
115
|
declare columns: MatrixAxis[];
|
package/DS1/3-unit/ds-menu.ts
CHANGED
|
@@ -222,7 +222,8 @@ export class Menu extends LitElement {
|
|
|
222
222
|
}
|
|
223
223
|
private onTriggerClick = (event: MouseEvent) => {
|
|
224
224
|
if (this.triggerMode === "context" || this.triggerMode === "manual" || event.defaultPrevented) return;
|
|
225
|
-
|
|
225
|
+
// A hover menu's trigger that is a link (`a href`, `ds-button href`) follows its link when pressed.
|
|
226
|
+
if (this.hover && this.trigger?.matches("a[href], ds-button[href]")) return;
|
|
226
227
|
this.focusOnOpen = true;
|
|
227
228
|
this.openingEdge = "first";
|
|
228
229
|
this.toggleFromTrigger(this.triggerMode === "submenu" || !this.open);
|
|
@@ -449,12 +450,15 @@ export class Menu extends LitElement {
|
|
|
449
450
|
const items = this.items(true); if (!items.some(item => this.enabled(item))) return;
|
|
450
451
|
const current = external ? items.findIndex(item => item.id === this.activeId) : items.findIndex(item => event.composedPath().includes(item));
|
|
451
452
|
const columns = Math.max(1, Math.floor(this.columns || 1));
|
|
453
|
+
// A menu laid out in one line (Context's bar) steps sideways, in the reading direction.
|
|
454
|
+
const across = this.getAttribute("aria-orientation") === "horizontal";
|
|
455
|
+
const forward = this.ownerDocument.defaultView?.getComputedStyle(this).direction === "rtl" ? -1 : 1;
|
|
452
456
|
let next: number;
|
|
453
457
|
switch (event.key) {
|
|
454
|
-
case "ArrowDown": next = columns > 1 ? this.gridStep(items, current, columns, 1) : this.step(items, current, 1, 1); break;
|
|
455
|
-
case "ArrowUp": next = columns > 1 ? this.gridStep(items, current, columns, -1) : this.step(items, current, 1, -1); break;
|
|
456
|
-
case "ArrowRight": if (columns === 1 || external) return; next = this.step(items, current, 1, 1); break;
|
|
457
|
-
case "ArrowLeft": if (columns === 1 || external) return; next = this.step(items, current, 1, -1); break;
|
|
458
|
+
case "ArrowDown": if (across) return; next = columns > 1 ? this.gridStep(items, current, columns, 1) : this.step(items, current, 1, 1); break;
|
|
459
|
+
case "ArrowUp": if (across) return; next = columns > 1 ? this.gridStep(items, current, columns, -1) : this.step(items, current, 1, -1); break;
|
|
460
|
+
case "ArrowRight": if (across) { next = this.step(items, current, 1, forward); break; } if (columns === 1 || external) return; next = this.step(items, current, 1, 1); break;
|
|
461
|
+
case "ArrowLeft": if (across) { next = this.step(items, current, 1, -forward); break; } if (columns === 1 || external) return; next = this.step(items, current, 1, -1); break;
|
|
458
462
|
case "Home": if (external) return; next = items.findIndex(item => this.enabled(item)); break;
|
|
459
463
|
case "End": if (external) return; next = this.lastEnabled(items); break;
|
|
460
464
|
case "Enter":
|
package/DS1/3-unit/ds-row.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { LitElement, html, unsafeCSS } from "lit";
|
|
|
2
2
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
3
3
|
import styles from "./styles/ds-row.css?inline";
|
|
4
4
|
import { define } from "../0-face/define";
|
|
5
|
+
import { CutFades } from "../0-face/cut-fade";
|
|
5
6
|
|
|
6
7
|
/** The values `aria-current` takes besides `page`. */
|
|
7
8
|
const CURRENT = new Set(["page", "step", "location", "date", "time", "true"]);
|
|
@@ -30,6 +31,14 @@ const CURRENT = new Set(["page", "step", "location", "date", "time", "true"]);
|
|
|
30
31
|
* @attr label - The accessible name, when the row's words do not say it.
|
|
31
32
|
* @attr target - Where a link opens (`_blank`, …).
|
|
32
33
|
* @attr rel - The link's relationship (`noopener`, …).
|
|
34
|
+
* A record's row puts its parts in classes: `ds-row__name` for the words,
|
|
35
|
+
* which hug and give way first, and `ds-row__value` for the figure or date at
|
|
36
|
+
* the row's end; a 16px picture (an avatar tile, a large icon) before the
|
|
37
|
+
* name stands on its square with the row's gap putting the words on the next.
|
|
38
|
+
* The element measures each name and marks it `data-cut="end"` while its
|
|
39
|
+
* words do not fit, so the stylesheet fades them over the last square, never
|
|
40
|
+
* an ellipsis; a `ds-text literal` name fades the same way.
|
|
41
|
+
*
|
|
33
42
|
* @slot - The row's content, inside its press target.
|
|
34
43
|
* @slot end - Controls of their own after the content, outside the press target.
|
|
35
44
|
* @fires ds-row-press - `{ href }`: the row was pressed. Cancel it to route a link yourself; a modified click on a link is left to the browser.
|
|
@@ -88,6 +97,12 @@ export class Row extends LitElement {
|
|
|
88
97
|
|
|
89
98
|
static styles = unsafeCSS(styles);
|
|
90
99
|
|
|
100
|
+
/** Marks each `.ds-row__name` `data-cut="end"` while its words are wider than its box, measured again as they resize or change. */
|
|
101
|
+
protected readonly cuts = new CutFades(this, { targets: () => this.querySelectorAll(":scope > .ds-row__name"), text: true });
|
|
102
|
+
|
|
103
|
+
/** Measures the names again, as when the slotted content changes. */
|
|
104
|
+
private measureNames = () => this.cuts.measure();
|
|
105
|
+
|
|
91
106
|
/** The `aria-current` value, or none. */
|
|
92
107
|
private get currentValue(): string | undefined {
|
|
93
108
|
const value = this.current;
|
|
@@ -111,10 +126,10 @@ export class Row extends LitElement {
|
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
render() {
|
|
114
|
-
if (!this.href && !this.interactive) return html`<slot></slot>`;
|
|
129
|
+
if (!this.href && !this.interactive) return html`<slot @slotchange=${this.measureNames}></slot>`;
|
|
115
130
|
const current = this.currentValue;
|
|
116
131
|
const label = this.label || undefined;
|
|
117
|
-
const content = html`<slot></slot>`;
|
|
132
|
+
const content = html`<slot @slotchange=${this.measureNames}></slot>`;
|
|
118
133
|
const target = this.href
|
|
119
134
|
? this.disabled
|
|
120
135
|
? html`<a class="target" part="target" role="link" aria-disabled="true" aria-label=${ifDefined(label)}>${content}</a>`
|
package/DS1/3-unit/ds-select.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { html, nothing, unsafeCSS, type PropertyValues, type TemplateResult } from "lit";
|
|
2
2
|
import { define } from "../0-face/define";
|
|
3
3
|
import { shortcutLabel } from "../0-face/keys";
|
|
4
|
-
import down from "../x-icon/down.svg?raw";
|
|
4
|
+
import down from "../x-icon/chevron-down.svg?raw";
|
|
5
5
|
import check from "../x-icon/check.svg?raw";
|
|
6
6
|
import menuStyles from "./styles/ds-menu.css?inline";
|
|
7
7
|
import styles from "./styles/ds-select.css?inline";
|
package/DS1/3-unit/ds-sidebar.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
|
2
2
|
import { repeat } from "lit/directives/repeat.js";
|
|
3
3
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
4
4
|
import { define } from "../0-face/define";
|
|
5
|
+
import { CutFades } from "../0-face/cut-fade";
|
|
5
6
|
import { treeStep } from "../0-face/sidebar";
|
|
6
7
|
import "../0-face/tooltips";
|
|
7
8
|
import "../2-core/ds-button";
|
|
@@ -28,6 +29,8 @@ export interface SidebarItem {
|
|
|
28
29
|
disabled?: boolean;
|
|
29
30
|
/** Small muted words at the row's end: a count, a size. */
|
|
30
31
|
meta?: string;
|
|
32
|
+
/** Small muted words just after the label, read with it: a version. */
|
|
33
|
+
detail?: string;
|
|
31
34
|
/** Optional application content following this navigation row. */
|
|
32
35
|
afterSlot?: string;
|
|
33
36
|
action?: { id: string; label: string; icon?: string; disabled?: boolean };
|
|
@@ -52,9 +55,15 @@ export interface SidebarMoveDetail { id: string; targetId: string; position: "be
|
|
|
52
55
|
* `0-face/sidebar.ts`). The application keeps the rows: it passes the
|
|
53
56
|
* visible ones in `items`, in order, and answers the events.
|
|
54
57
|
*
|
|
58
|
+
* With `narrow`, the navigation is eight squares wide and each row hugs its
|
|
59
|
+
* words: the pointer's and the current row's fill wraps the label, its meta
|
|
60
|
+
* and its disclosure, 4px either side, instead of running across the column.
|
|
61
|
+
* For an application's few places beside its work.
|
|
62
|
+
*
|
|
55
63
|
* @element ds-sidebar
|
|
56
64
|
* @attr label - The navigation's or the tree's accessible name.
|
|
57
65
|
* @attr tree - A tree of nested things instead of navigation.
|
|
66
|
+
* @attr narrow - Navigation eight squares wide, each row hugging its words.
|
|
58
67
|
* @fires sidebar-toggle - `{ id, expanded }`: a row asks to open or close.
|
|
59
68
|
* @fires sidebar-activate - `{ id }`: a row was pressed (navigation), or Enter or a double click opened one (a tree).
|
|
60
69
|
* @fires sidebar-select - `{ id }`: a click, Space or Enter chose a tree row.
|
|
@@ -69,6 +78,7 @@ export class Sidebar extends LitElement {
|
|
|
69
78
|
collapseIcon: { type: String, attribute: "collapse-icon" },
|
|
70
79
|
disclosurePosition: { type: String, attribute: "disclosure-position", reflect: true },
|
|
71
80
|
tree: { type: Boolean, reflect: true },
|
|
81
|
+
narrow: { type: Boolean, reflect: true },
|
|
72
82
|
reorderable: { type: Boolean, reflect: true },
|
|
73
83
|
};
|
|
74
84
|
declare items: SidebarItem[];
|
|
@@ -80,9 +90,13 @@ export class Sidebar extends LitElement {
|
|
|
80
90
|
/** Place navigation disclosures before the label; default preserves trailing disclosures. */
|
|
81
91
|
declare disclosurePosition?: "start" | "end";
|
|
82
92
|
declare tree: boolean;
|
|
93
|
+
/** Eight squares wide, each row hugging its words (navigation only). */
|
|
94
|
+
declare narrow: boolean;
|
|
83
95
|
declare reorderable: boolean;
|
|
84
96
|
private dragId?: string;
|
|
85
97
|
static styles = unsafeCSS(styles);
|
|
98
|
+
/** Words cut short fade over their last square, never an ellipsis: marks them `data-cut="end"` while they do not fit. */
|
|
99
|
+
protected readonly cuts = new CutFades(this, { selector: ".name, .tree .label" });
|
|
86
100
|
|
|
87
101
|
/** In a tree, the row that holds the Tab stop. */
|
|
88
102
|
private focusId?: string;
|
|
@@ -93,6 +107,7 @@ export class Sidebar extends LitElement {
|
|
|
93
107
|
this.label = "Navigation";
|
|
94
108
|
this.empty = "No items";
|
|
95
109
|
this.tree = false;
|
|
110
|
+
this.narrow = false;
|
|
96
111
|
this.reorderable = false;
|
|
97
112
|
}
|
|
98
113
|
|
|
@@ -233,7 +248,7 @@ export class Sidebar extends LitElement {
|
|
|
233
248
|
@focus=${() => { this.focusId = item.id; }}>
|
|
234
249
|
<span class="disclosure" aria-hidden="true">${item.expanded === undefined ? nothing : html`<ds-icon type="right" ?data-open=${item.expanded}></ds-icon>`}</span>
|
|
235
250
|
${item.icon ? html`<span class="icon" aria-hidden="true"><ds-icon type=${item.icon}></ds-icon></span>` : nothing}
|
|
236
|
-
<span class="label">${item.label}</span>
|
|
251
|
+
<span class="label">${item.label}${item.detail ? html`<span class="detail">${item.detail}</span>` : nothing}</span>
|
|
237
252
|
${item.meta ? html`<span class="meta">${item.meta}</span>` : nothing}
|
|
238
253
|
</div>`;
|
|
239
254
|
})}
|
|
@@ -345,12 +360,12 @@ export class Sidebar extends LitElement {
|
|
|
345
360
|
${item.href && !item.disabled ? html`
|
|
346
361
|
<a href=${item.href} draggable=${ifDefined(this.reorderable ? "false" : undefined)} data-item=${item.id} aria-current=${ifDefined(item.current ? "page" : undefined)}
|
|
347
362
|
@click=${(event: MouseEvent) => this.activate(event, item)}
|
|
348
|
-
@keydown=${(event: KeyboardEvent) => this.navigate(event, item)}><span class="name">${item.icon ? html`<ds-icon type=${item.icon} aria-hidden="true"></ds-icon>` : nothing}${item.label}</span></a>` : html`
|
|
363
|
+
@keydown=${(event: KeyboardEvent) => this.navigate(event, item)}><span class="name">${item.icon ? html`<ds-icon type=${item.icon} aria-hidden="true"></ds-icon>` : nothing}${item.label}${item.detail ? html`<span class="detail">${item.detail}</span>` : nothing}</span></a>` : html`
|
|
349
364
|
<button type="button" data-item=${item.id} ?disabled=${item.disabled}
|
|
350
365
|
aria-expanded=${ifDefined(item.expanded === undefined ? undefined : String(item.expanded))}
|
|
351
366
|
aria-current=${ifDefined(item.current ? "page" : undefined)}
|
|
352
367
|
@click=${(event: MouseEvent) => this.activate(event, item)}
|
|
353
|
-
@keydown=${(event: KeyboardEvent) => this.navigate(event, item)}><span class="name">${item.icon ? html`<ds-icon type=${item.icon} aria-hidden="true"></ds-icon>` : nothing}${item.label}</span></button>`}
|
|
368
|
+
@keydown=${(event: KeyboardEvent) => this.navigate(event, item)}><span class="name">${item.icon ? html`<ds-icon type=${item.icon} aria-hidden="true"></ds-icon>` : nothing}${item.label}${item.detail ? html`<span class="detail">${item.detail}</span>` : nothing}</span></button>`}
|
|
354
369
|
</ds-button>
|
|
355
370
|
${this.disclosurePosition !== "start" ? this.renderDisclosure(item) : nothing}
|
|
356
371
|
<span class="spacer" aria-hidden="true"></span>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { LitElement, html, nothing, unsafeCSS } from 'lit';
|
|
2
|
+
import { define } from '../0-face/define';
|
|
3
|
+
import { CutFades } from '../0-face/cut-fade';
|
|
4
|
+
import { getText } from '../0-face/i18n';
|
|
5
|
+
import '../0-face/tooltips';
|
|
6
|
+
import '../2-core/ds-text';
|
|
7
|
+
import styles from './styles/ds-table-of-contents.css?inline';
|
|
8
|
+
|
|
9
|
+
export interface TableOfContentsItem { href: string; label: string; depth?: number; }
|
|
10
|
+
|
|
11
|
+
/** A page's section links. Placement belongs to the page, not this Unit.
|
|
12
|
+
* Supply items or slot native anchors with data-depth. Same-page links track
|
|
13
|
+
* their headings inside the actual scrolling container, including a shadow root.
|
|
14
|
+
* @element ds-table-of-contents
|
|
15
|
+
* @fires toc-change - { href }: the section in view changed.
|
|
16
|
+
*/
|
|
17
|
+
export class TableOfContents extends LitElement {
|
|
18
|
+
static properties = {
|
|
19
|
+
items: { attribute: false }, label: { type: String }, literal: { type: Boolean },
|
|
20
|
+
target: { attribute: false }, current: { state: true },
|
|
21
|
+
};
|
|
22
|
+
static styles = unsafeCSS(styles);
|
|
23
|
+
/** A cut label fades over its last square, never an ellipsis: marks it `data-cut="end"` while it does not fit. */
|
|
24
|
+
protected readonly cuts = new CutFades(this, { selector: 'a', targets: () => this.querySelectorAll(':scope > a'), text: true });
|
|
25
|
+
declare items: TableOfContentsItem[];
|
|
26
|
+
declare label: string;
|
|
27
|
+
declare literal: boolean;
|
|
28
|
+
/** Optional content scope, especially when the contents stand inside another component's shadow. */
|
|
29
|
+
declare target?: HTMLElement;
|
|
30
|
+
declare current: string;
|
|
31
|
+
private links: HTMLAnchorElement[] = [];
|
|
32
|
+
private sections: { link: HTMLAnchorElement; heading: HTMLElement }[] = [];
|
|
33
|
+
private scroller: HTMLElement | null = null;
|
|
34
|
+
private frame = 0;
|
|
35
|
+
private observer?: MutationObserver;
|
|
36
|
+
private resize?: ResizeObserver;
|
|
37
|
+
private readonly relabel = () => this.requestUpdate();
|
|
38
|
+
constructor() {
|
|
39
|
+
super(); this.items = []; this.label = 'Contents'; this.literal = false; this.current = '';
|
|
40
|
+
}
|
|
41
|
+
connectedCallback() {
|
|
42
|
+
super.connectedCallback();
|
|
43
|
+
this.addEventListener('click', this.follow);
|
|
44
|
+
window.addEventListener('scroll', this.schedule, { passive: true });
|
|
45
|
+
window.addEventListener('resize', this.schedule, { passive: true });
|
|
46
|
+
window.addEventListener('hashchange', this.schedule);
|
|
47
|
+
window.addEventListener('language-changed', this.relabel);
|
|
48
|
+
window.addEventListener('translations-loaded', this.relabel);
|
|
49
|
+
this.observer = new MutationObserver(() => this.refresh());
|
|
50
|
+
this.observer.observe(this, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ['href', 'data-depth'] });
|
|
51
|
+
if (typeof ResizeObserver !== 'undefined') this.resize = new ResizeObserver(this.schedule);
|
|
52
|
+
void this.updateComplete.then(() => { if (this.isConnected) this.refresh(); });
|
|
53
|
+
void this.ownerDocument.fonts?.ready.then(this.schedule);
|
|
54
|
+
}
|
|
55
|
+
disconnectedCallback() {
|
|
56
|
+
this.removeEventListener('click', this.follow);
|
|
57
|
+
window.removeEventListener('scroll', this.schedule);
|
|
58
|
+
this.scroller?.removeEventListener('scroll', this.schedule);
|
|
59
|
+
window.removeEventListener('resize', this.schedule);
|
|
60
|
+
window.removeEventListener('hashchange', this.schedule);
|
|
61
|
+
window.removeEventListener('language-changed', this.relabel);
|
|
62
|
+
window.removeEventListener('translations-loaded', this.relabel);
|
|
63
|
+
this.observer?.disconnect(); this.resize?.disconnect(); cancelAnimationFrame(this.frame);
|
|
64
|
+
super.disconnectedCallback();
|
|
65
|
+
}
|
|
66
|
+
protected updated(changed: Map<PropertyKey, unknown>) {
|
|
67
|
+
if (changed.has('items') || changed.has('target')) this.refresh();
|
|
68
|
+
}
|
|
69
|
+
private destination(link: HTMLAnchorElement): HTMLElement | null {
|
|
70
|
+
try {
|
|
71
|
+
const url = new URL(link.href, this.ownerDocument.baseURI);
|
|
72
|
+
const page = new URL(this.ownerDocument.URL);
|
|
73
|
+
if (!url.hash || url.origin !== page.origin || url.pathname !== page.pathname || url.search !== page.search) return null;
|
|
74
|
+
const id = decodeURIComponent(url.hash.slice(1));
|
|
75
|
+
if (this.target) return [...this.target.querySelectorAll<HTMLElement>('[id]')].find(node => node.id === id) ?? null;
|
|
76
|
+
const root = this.getRootNode() as Document | ShadowRoot;
|
|
77
|
+
return root.getElementById(id) ?? null;
|
|
78
|
+
} catch { return null; }
|
|
79
|
+
}
|
|
80
|
+
/** Read links and targets again after replacing content or moving the Unit. */
|
|
81
|
+
refresh() {
|
|
82
|
+
if (!this.isConnected) return;
|
|
83
|
+
this.links = this.items.length ? [...this.renderRoot.querySelectorAll<HTMLAnchorElement>('a')]
|
|
84
|
+
: [...this.querySelectorAll<HTMLAnchorElement>('a[href]')];
|
|
85
|
+
this.sections = this.links.flatMap(link => {
|
|
86
|
+
const heading = this.destination(link);
|
|
87
|
+
return heading ? [{ link, heading }] : [];
|
|
88
|
+
});
|
|
89
|
+
for (const link of this.links) {
|
|
90
|
+
const depth = Number(link.dataset.depth ?? 0);
|
|
91
|
+
link.style.setProperty('--toc-depth', String(Number.isFinite(depth) ? Math.max(0, depth) : 0));
|
|
92
|
+
}
|
|
93
|
+
this.scroller?.removeEventListener('scroll', this.schedule);
|
|
94
|
+
this.scroller = null;
|
|
95
|
+
const parentOf = (node: Element): HTMLElement | null => node.parentElement ?? (node.getRootNode() instanceof ShadowRoot ? (node.getRootNode() as ShadowRoot).host as HTMLElement : null);
|
|
96
|
+
for (let parent = this.sections[0] ? parentOf(this.sections[0].heading) : null; parent; parent = parentOf(parent)) {
|
|
97
|
+
if (/(auto|scroll)/.test(getComputedStyle(parent).overflowY)) { this.scroller = parent; break; }
|
|
98
|
+
}
|
|
99
|
+
this.scroller?.addEventListener('scroll', this.schedule, { passive: true });
|
|
100
|
+
this.resize?.disconnect();
|
|
101
|
+
this.resize?.observe(this);
|
|
102
|
+
if (this.target) this.resize?.observe(this.target);
|
|
103
|
+
if (this.scroller) this.resize?.observe(this.scroller);
|
|
104
|
+
this.schedule();
|
|
105
|
+
}
|
|
106
|
+
private schedule = () => {
|
|
107
|
+
if (!this.isConnected) return;
|
|
108
|
+
cancelAnimationFrame(this.frame);
|
|
109
|
+
this.frame = requestAnimationFrame(() => this.track());
|
|
110
|
+
};
|
|
111
|
+
private track() {
|
|
112
|
+
for (const link of this.links) {
|
|
113
|
+
if (link.scrollWidth > link.clientWidth) link.setAttribute('data-tooltip', link.textContent?.trim() ?? '');
|
|
114
|
+
else link.removeAttribute('data-tooltip');
|
|
115
|
+
}
|
|
116
|
+
if (!this.sections.length) { this.mark(''); return; }
|
|
117
|
+
const box = this.scroller?.getBoundingClientRect();
|
|
118
|
+
const top = box?.top ?? 0;
|
|
119
|
+
const height = this.scroller?.clientHeight ?? window.innerHeight;
|
|
120
|
+
const scrollTop = this.scroller?.scrollTop ?? window.scrollY;
|
|
121
|
+
const scrollHeight = this.scroller?.scrollHeight ?? this.ownerDocument.documentElement.scrollHeight;
|
|
122
|
+
const end = scrollTop > 0 && scrollTop + height >= scrollHeight - 1;
|
|
123
|
+
// The rendered row resolves nested scale and calc() tokens to actual pixels.
|
|
124
|
+
const unit = this.renderRoot.querySelector<HTMLElement>('.title')?.getBoundingClientRect().height || 20;
|
|
125
|
+
const line = top + (end ? height : unit);
|
|
126
|
+
let current = this.sections[0].link.getAttribute('href')!;
|
|
127
|
+
for (const { link, heading } of this.sections) {
|
|
128
|
+
if (heading.getBoundingClientRect().top <= line) current = link.getAttribute('href')!;
|
|
129
|
+
else break;
|
|
130
|
+
}
|
|
131
|
+
this.mark(current);
|
|
132
|
+
}
|
|
133
|
+
private mark(href: string) {
|
|
134
|
+
for (const link of this.links) {
|
|
135
|
+
if (link.getAttribute('href') === href) link.setAttribute('aria-current', 'location');
|
|
136
|
+
else link.removeAttribute('aria-current');
|
|
137
|
+
}
|
|
138
|
+
if (this.current === href) return;
|
|
139
|
+
this.current = href;
|
|
140
|
+
this.dispatchEvent(new CustomEvent('toc-change', { detail: { href }, bubbles: true, composed: true }));
|
|
141
|
+
}
|
|
142
|
+
private follow = (event: MouseEvent) => {
|
|
143
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
144
|
+
const link = event.composedPath().find((node): node is HTMLAnchorElement => node instanceof HTMLAnchorElement);
|
|
145
|
+
if (!link || !this.links.includes(link) || link.target === '_blank' || link.hasAttribute('download')) return;
|
|
146
|
+
const heading = this.destination(link); if (!heading) return;
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
heading.scrollIntoView({ block: 'start', behavior: 'auto' });
|
|
149
|
+
if (!heading.hasAttribute('tabindex')) heading.setAttribute('tabindex', '-1');
|
|
150
|
+
heading.focus({ preventScroll: true });
|
|
151
|
+
history.pushState(history.state, '', link.href);
|
|
152
|
+
this.mark(link.getAttribute('href')!);
|
|
153
|
+
};
|
|
154
|
+
render() {
|
|
155
|
+
const words = this.label || 'Contents';
|
|
156
|
+
const label = this.literal ? words : getText(words) || words;
|
|
157
|
+
return html`<nav aria-label=${label} part="navigation">
|
|
158
|
+
<div class="title"><ds-text literal strong role="heading" aria-level="2" part="title">${label}</ds-text></div>
|
|
159
|
+
<div class="links" part="links"><slot @slotchange=${() => this.refresh()}>
|
|
160
|
+
${this.items.map(item => html`<a href=${item.href} data-depth=${item.depth ?? 0} aria-current=${this.current === item.href ? 'location' : nothing} part="link">${item.label}</a>`)}
|
|
161
|
+
</slot></div>
|
|
162
|
+
</nav>`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
define('ds-table-of-contents', TableOfContents);
|
|
166
|
+
declare global { interface HTMLElementTagNameMap { 'ds-table-of-contents': TableOfContents; } }
|