@0001-labs/design-system-1 0.3.0-alpha.28 → 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/material.css +67 -0
- package/DS1/1-root/notice.css +10 -2
- package/DS1/1-root/one.css +14 -7
- 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 +3 -3
- 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/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 +5514 -2077
- 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 +23 -12
- 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
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image focus: where a photo's subject is, so a picture cut to its box
|
|
3
|
+
* (`object-fit: cover`) keeps it in view instead of its middle. A person's
|
|
4
|
+
* face first, then whatever in the picture holds the most detail. Plain
|
|
5
|
+
* TypeScript with no imports, for the browser and for a build script alike.
|
|
6
|
+
*
|
|
7
|
+
* The focus is a point of the picture, across and down from 0 to 1, and it is
|
|
8
|
+
* written as the picture's `object-position` (`objectPosition()`), so a
|
|
9
|
+
* cover crop of any shape keeps that point in view. Work it out once, where
|
|
10
|
+
* the page is built, and write it into the markup, so the first paint is
|
|
11
|
+
* already cut right. On a Mac, `focus-vision.swift` finds the faces and the
|
|
12
|
+
* salient part with Apple's Vision framework, and `focusFromRegions()` turns
|
|
13
|
+
* them into the focus; elsewhere, or where it finds nothing, `focusOf()`
|
|
14
|
+
* reads the pixels:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // swift 0-face/focus-vision.swift *.jpg > regions.json
|
|
18
|
+
* import { focusFromRegions, focusOf, objectPosition } from "./0-face/focus.ts";
|
|
19
|
+
* const focus = focusFromRegions(regions[name]) ?? focusOf(data, info.width, info.height, info.channels);
|
|
20
|
+
* // <img src="…" style="object-position: 50% 18%">
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* A page with no build step marks a picture `data-ds-focus="auto"` and calls
|
|
24
|
+
* `startFocus()`: once the picture has loaded, its focus is found and kept in
|
|
25
|
+
* the browser, so it is right from the first paint on the next visit. A
|
|
26
|
+
* picture whose focus a person chose says so, `data-ds-focus="40% 20%"`, and
|
|
27
|
+
* is never measured. A picture from another host without CORS cannot be read
|
|
28
|
+
* and keeps its middle.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** A point of a picture, across (`x`) and down (`y`), each from 0 to 1. */
|
|
32
|
+
export interface Focus { x: number; y: number }
|
|
33
|
+
|
|
34
|
+
export const CENTRE: Focus = { x: 0.5, y: 0.5 };
|
|
35
|
+
|
|
36
|
+
/** The width a picture is measured at; enough to find a face, and cheap. */
|
|
37
|
+
export const FOCUS_SAMPLE = 64;
|
|
38
|
+
|
|
39
|
+
/** Whether a pixel's colour is skin, in YCbCr, for any skin tone. */
|
|
40
|
+
function isSkin(r: number, g: number, b: number): boolean {
|
|
41
|
+
const y = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
42
|
+
const cb = 128 - 0.168736 * r - 0.331264 * g + 0.5 * b;
|
|
43
|
+
const cr = 128 + 0.5 * r - 0.418688 * g - 0.081312 * b;
|
|
44
|
+
return y > 40 && cb >= 77 && cb <= 127 && cr >= 137 && cr <= 173 && r > g && r > b;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const clamp = (value: number) => Math.min(1, Math.max(0, value));
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The focus of a picture from its pixels (RGB or RGBA, row by row), measured
|
|
51
|
+
* small (about `FOCUS_SAMPLE` across). Skin that gathers into a face wins:
|
|
52
|
+
* the highest band of rows dense with skin, since a face stands above hands
|
|
53
|
+
* and arms. Without one, the centre of the picture's detail (where neighbouring
|
|
54
|
+
* pixels differ most), drawn a little towards the middle so a busy edge does
|
|
55
|
+
* not take the crop.
|
|
56
|
+
*/
|
|
57
|
+
export function focusOf(pixels: ArrayLike<number>, width: number, height: number, channels = 4): Focus {
|
|
58
|
+
if (width < 2 || height < 2) return CENTRE;
|
|
59
|
+
const at = (x: number, y: number) => (y * width + x) * channels;
|
|
60
|
+
const luma = new Float32Array(width * height);
|
|
61
|
+
const skin = new Uint8Array(width * height);
|
|
62
|
+
let skinCount = 0;
|
|
63
|
+
for (let y = 0; y < height; y++) {
|
|
64
|
+
for (let x = 0; x < width; x++) {
|
|
65
|
+
const i = at(x, y);
|
|
66
|
+
const r = pixels[i]!, g = pixels[i + 1]!, b = pixels[i + 2]!;
|
|
67
|
+
luma[y * width + x] = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
68
|
+
if (isSkin(r, g, b)) { skin[y * width + x] = 1; skinCount++; }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// A face: skin over at least half a percent of the picture, in a band of rows.
|
|
73
|
+
if (skinCount >= width * height * 0.005) {
|
|
74
|
+
const band = Math.max(2, Math.round(height / 10));
|
|
75
|
+
const rows = new Float32Array(height);
|
|
76
|
+
for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) rows[y] += skin[y * width + x]!;
|
|
77
|
+
let densest = 0;
|
|
78
|
+
const bands: number[] = [];
|
|
79
|
+
for (let y = 0; y + band <= height; y++) {
|
|
80
|
+
let sum = 0;
|
|
81
|
+
for (let k = 0; k < band; k++) sum += rows[y + k]!;
|
|
82
|
+
bands.push(sum);
|
|
83
|
+
densest = Math.max(densest, sum);
|
|
84
|
+
}
|
|
85
|
+
const top = bands.findIndex(sum => sum >= densest * 0.45);
|
|
86
|
+
if (top >= 0) {
|
|
87
|
+
let sx = 0, sy = 0, n = 0;
|
|
88
|
+
for (let y = top; y < Math.min(height, top + band * 2); y++) {
|
|
89
|
+
for (let x = 0; x < width; x++) if (skin[y * width + x]) { sx += x; sy += y; n++; }
|
|
90
|
+
}
|
|
91
|
+
if (n) return { x: clamp((sx / n + 0.5) / width), y: clamp((sy / n + 0.5) / height) };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Otherwise the picture's detail.
|
|
96
|
+
let sx = 0, sy = 0, total = 0;
|
|
97
|
+
for (let y = 1; y < height - 1; y++) {
|
|
98
|
+
for (let x = 1; x < width - 1; x++) {
|
|
99
|
+
const i = y * width + x;
|
|
100
|
+
const energy = Math.abs(luma[i + 1]! - luma[i - 1]!) + Math.abs(luma[i + width]! - luma[i - width]!);
|
|
101
|
+
sx += x * energy; sy += y * energy; total += energy;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!total) return CENTRE;
|
|
105
|
+
const pull = 0.35;
|
|
106
|
+
return {
|
|
107
|
+
x: clamp(((sx / total + 0.5) / width) * (1 - pull) + 0.5 * pull),
|
|
108
|
+
y: clamp(((sy / total + 0.5) / height) * (1 - pull) + 0.5 * pull),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** A part of a picture, as fractions of it from its top left corner. */
|
|
113
|
+
export interface Region { x: number; y: number; w: number; h: number }
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The focus from what a detector found (`focus-vision.swift`: Apple's face
|
|
117
|
+
* detection and attention-based saliency), or `undefined` when it found
|
|
118
|
+
* nothing. Faces win: the point between them across, and down a little above
|
|
119
|
+
* the top of the highest, so a crop keeps the heads whole with room above
|
|
120
|
+
* them. Otherwise the middle of everything salient.
|
|
121
|
+
*/
|
|
122
|
+
export function focusFromRegions(found: { faces?: Region[]; salient?: Region[] }): Focus | undefined {
|
|
123
|
+
const faces = (found.faces ?? []).filter(face => face.w * face.h > 0.0005);
|
|
124
|
+
if (faces.length) {
|
|
125
|
+
const biggest = Math.max(...faces.map(face => face.w * face.h));
|
|
126
|
+
const kept = faces.filter(face => face.w * face.h >= biggest * 0.25);
|
|
127
|
+
const left = Math.min(...kept.map(face => face.x));
|
|
128
|
+
const right = Math.max(...kept.map(face => face.x + face.w));
|
|
129
|
+
const top = Math.min(...kept.map(face => face.y));
|
|
130
|
+
const height = Math.max(...kept.map(face => face.h));
|
|
131
|
+
return { x: clamp((left + right) / 2), y: clamp(top - height * 0.35) };
|
|
132
|
+
}
|
|
133
|
+
const salient = found.salient ?? [];
|
|
134
|
+
if (!salient.length) return undefined;
|
|
135
|
+
const left = Math.min(...salient.map(r => r.x));
|
|
136
|
+
const right = Math.max(...salient.map(r => r.x + r.w));
|
|
137
|
+
const top = Math.min(...salient.map(r => r.y));
|
|
138
|
+
const bottom = Math.max(...salient.map(r => r.y + r.h));
|
|
139
|
+
return { x: clamp((left + right) / 2), y: clamp((top + bottom) / 2) };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The focus as CSS `object-position`, in whole percents. */
|
|
143
|
+
export function objectPosition(focus: Focus): string {
|
|
144
|
+
return `${Math.round(focus.x * 100)}% ${Math.round(focus.y * 100)}%`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const KEY = "ds-focus:";
|
|
148
|
+
|
|
149
|
+
/** Finds and sets the focus of one picture marked `data-ds-focus="auto"`, once it has loaded. */
|
|
150
|
+
export function focusImage(image: HTMLImageElement): void {
|
|
151
|
+
const chosen = image.dataset.dsFocus;
|
|
152
|
+
if (chosen && chosen !== "auto") { image.style.objectPosition = chosen; return; }
|
|
153
|
+
const source = image.currentSrc || image.src;
|
|
154
|
+
try {
|
|
155
|
+
const kept = localStorage.getItem(KEY + source);
|
|
156
|
+
if (kept) { image.style.objectPosition = kept; return; }
|
|
157
|
+
} catch { /* Storage can be blocked. */ }
|
|
158
|
+
const measure = () => {
|
|
159
|
+
if (!image.naturalWidth) return;
|
|
160
|
+
const width = FOCUS_SAMPLE;
|
|
161
|
+
const height = Math.max(2, Math.round((image.naturalHeight / image.naturalWidth) * width));
|
|
162
|
+
const canvas = document.createElement("canvas");
|
|
163
|
+
canvas.width = width;
|
|
164
|
+
canvas.height = height;
|
|
165
|
+
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
166
|
+
if (!context) return;
|
|
167
|
+
try {
|
|
168
|
+
context.drawImage(image, 0, 0, width, height);
|
|
169
|
+
const position = objectPosition(focusOf(context.getImageData(0, 0, width, height).data, width, height, 4));
|
|
170
|
+
image.style.objectPosition = position;
|
|
171
|
+
try { localStorage.setItem(KEY + source, position); } catch { /* Storage can be blocked. */ }
|
|
172
|
+
} catch { /* A picture from another host without CORS cannot be read; it keeps its middle. */ }
|
|
173
|
+
};
|
|
174
|
+
if (image.complete) measure();
|
|
175
|
+
else image.addEventListener("load", measure, { once: true });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Sets the focus of every picture marked `data-ds-focus` in `root`. */
|
|
179
|
+
export function startFocus(root: ParentNode = document): void {
|
|
180
|
+
for (const image of root.querySelectorAll<HTMLImageElement>("img[data-ds-focus]")) focusImage(image);
|
|
181
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"DM Sans": {
|
|
3
|
+
"ascent": 0.992,
|
|
4
|
+
"descent": 0.31,
|
|
5
|
+
"capHeight": 0.7
|
|
6
|
+
},
|
|
7
|
+
"Inter": {
|
|
8
|
+
"ascent": 0.9688,
|
|
9
|
+
"descent": 0.2412,
|
|
10
|
+
"capHeight": 0.7275
|
|
11
|
+
},
|
|
12
|
+
"JetBrains Mono": {
|
|
13
|
+
"ascent": 1.02,
|
|
14
|
+
"descent": 0.3,
|
|
15
|
+
"capHeight": 0.73
|
|
16
|
+
},
|
|
17
|
+
"Lora": {
|
|
18
|
+
"ascent": 1.006,
|
|
19
|
+
"descent": 0.274,
|
|
20
|
+
"capHeight": 0.7
|
|
21
|
+
},
|
|
22
|
+
"Manrope": {
|
|
23
|
+
"ascent": 1.066,
|
|
24
|
+
"descent": 0.3,
|
|
25
|
+
"capHeight": 0.72
|
|
26
|
+
},
|
|
27
|
+
"Montserrat": {
|
|
28
|
+
"ascent": 0.968,
|
|
29
|
+
"descent": 0.251,
|
|
30
|
+
"capHeight": 0.7
|
|
31
|
+
},
|
|
32
|
+
"Noto Sans": {
|
|
33
|
+
"ascent": 1.069,
|
|
34
|
+
"descent": 0.293,
|
|
35
|
+
"capHeight": 0.714
|
|
36
|
+
},
|
|
37
|
+
"Noto Sans JP": {
|
|
38
|
+
"ascent": 1.16,
|
|
39
|
+
"descent": 0.288,
|
|
40
|
+
"capHeight": 0.733
|
|
41
|
+
},
|
|
42
|
+
"Nunito": {
|
|
43
|
+
"ascent": 1.011,
|
|
44
|
+
"descent": 0.353,
|
|
45
|
+
"capHeight": 0.705
|
|
46
|
+
},
|
|
47
|
+
"Open Sans": {
|
|
48
|
+
"ascent": 1.0688,
|
|
49
|
+
"descent": 0.293,
|
|
50
|
+
"capHeight": 0.7139
|
|
51
|
+
},
|
|
52
|
+
"Outfit": {
|
|
53
|
+
"ascent": 1,
|
|
54
|
+
"descent": 0.26,
|
|
55
|
+
"capHeight": 0.694
|
|
56
|
+
},
|
|
57
|
+
"Playfair Display": {
|
|
58
|
+
"ascent": 1.082,
|
|
59
|
+
"descent": 0.251,
|
|
60
|
+
"capHeight": 0.708
|
|
61
|
+
},
|
|
62
|
+
"Poppins": {
|
|
63
|
+
"ascent": 1.05,
|
|
64
|
+
"descent": 0.35,
|
|
65
|
+
"capHeight": 0.698
|
|
66
|
+
},
|
|
67
|
+
"Raleway": {
|
|
68
|
+
"ascent": 0.94,
|
|
69
|
+
"descent": 0.234,
|
|
70
|
+
"capHeight": 0.71
|
|
71
|
+
},
|
|
72
|
+
"Roboto": {
|
|
73
|
+
"ascent": 0.9277,
|
|
74
|
+
"descent": 0.2441,
|
|
75
|
+
"capHeight": 0.7109
|
|
76
|
+
},
|
|
77
|
+
"Rubik": {
|
|
78
|
+
"ascent": 0.935,
|
|
79
|
+
"descent": 0.25,
|
|
80
|
+
"capHeight": 0.7
|
|
81
|
+
},
|
|
82
|
+
"Source Sans 3": {
|
|
83
|
+
"ascent": 1.024,
|
|
84
|
+
"descent": 0.4,
|
|
85
|
+
"capHeight": 0.66
|
|
86
|
+
},
|
|
87
|
+
"Source Serif 4": {
|
|
88
|
+
"ascent": 1.036,
|
|
89
|
+
"descent": 0.335,
|
|
90
|
+
"capHeight": 0.67
|
|
91
|
+
},
|
|
92
|
+
"Urbanist": {
|
|
93
|
+
"ascent": 0.95,
|
|
94
|
+
"descent": 0.25,
|
|
95
|
+
"capHeight": 0.7
|
|
96
|
+
},
|
|
97
|
+
"Work Sans": {
|
|
98
|
+
"ascent": 0.93,
|
|
99
|
+
"descent": 0.243,
|
|
100
|
+
"capHeight": 0.66
|
|
101
|
+
}
|
|
102
|
+
}
|
package/DS1/0-face/grid.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { createLayoutInspector } from './layout-inspector';
|
|
2
2
|
import { initGridFit } from './grid-fit';
|
|
3
|
+
import { initConstraintShortcut } from './constraint-panel';
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
+
/** The presses of one key, each within 800ms of the last, that toggle an overlay. */
|
|
6
|
+
export const GRID_PRESSES = 5;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Five presses of G toggle the grid and five of L inspect the layout, on every
|
|
10
|
+
* page that loads this module and for everyone who reads it: never put them
|
|
11
|
+
* behind a user, an owner or a development check. Escape hides both. Presses
|
|
12
|
+
* typed into a field, with a modifier or held down never count, and any other
|
|
13
|
+
* key starts the count again.
|
|
14
|
+
* A nested scrolling viewport opts in with data-ds-grid-scroll: its grid follows
|
|
15
|
+
* its content while the page grid remains aligned outside the viewport.
|
|
16
|
+
*/
|
|
5
17
|
export function initGridShortcut(): void {
|
|
6
18
|
if (typeof document === "undefined") return;
|
|
7
19
|
const root = document.documentElement;
|
|
@@ -9,6 +21,8 @@ export function initGridShortcut(): void {
|
|
|
9
21
|
root.setAttribute("data-ds-grid-ready", "");
|
|
10
22
|
root.setAttribute("data-design-system", "1");
|
|
11
23
|
initGridFit();
|
|
24
|
+
// Five presses of C, for the page's owner alone (constraint-panel.ts).
|
|
25
|
+
initConstraintShortcut();
|
|
12
26
|
|
|
13
27
|
const overlay = document.createElement("div");
|
|
14
28
|
overlay.setAttribute("data-ds-grid-overlay", "");
|
|
@@ -44,18 +58,61 @@ export function initGridShortcut(): void {
|
|
|
44
58
|
document.body.appendChild(overlay);
|
|
45
59
|
const layout = createLayoutInspector();
|
|
46
60
|
|
|
61
|
+
const pageGrid = shadow.querySelector<HTMLElement>('.grid')!;
|
|
62
|
+
const scopedGrids = new Map<HTMLElement, HTMLElement>();
|
|
63
|
+
let tracking = false;
|
|
64
|
+
const resize = new ResizeObserver(() => { if (tracking) updatePosition(); });
|
|
65
|
+
const regionsChanged = new MutationObserver(() => { if (tracking) updatePosition(); });
|
|
47
66
|
const updatePosition = () => {
|
|
48
67
|
overlay.style.setProperty("--ds-grid-scroll-x", `${window.scrollX}px`);
|
|
49
68
|
overlay.style.setProperty("--ds-grid-scroll-y", `${window.scrollY}px`);
|
|
69
|
+
const present = new Set<HTMLElement>();
|
|
70
|
+
const holes: string[] = [];
|
|
71
|
+
document.querySelectorAll<HTMLElement>('[data-ds-grid-scroll]').forEach(element => {
|
|
72
|
+
const rect = element.getBoundingClientRect();
|
|
73
|
+
let left = rect.left + element.clientLeft, top = rect.top + element.clientTop;
|
|
74
|
+
let right = left + element.clientWidth, bottom = top + element.clientHeight;
|
|
75
|
+
// The overlay must respect enclosing scroll viewports as the content does.
|
|
76
|
+
for (let parent = element.parentElement; parent; parent = parent.parentElement) {
|
|
77
|
+
const style = getComputedStyle(parent), box = parent.getBoundingClientRect();
|
|
78
|
+
if (/(auto|scroll|hidden|clip)/.test(style.overflowX)) { left = Math.max(left, box.left + parent.clientLeft); right = Math.min(right, box.left + parent.clientLeft + parent.clientWidth); }
|
|
79
|
+
if (/(auto|scroll|hidden|clip)/.test(style.overflowY)) { top = Math.max(top, box.top + parent.clientTop); bottom = Math.min(bottom, box.top + parent.clientTop + parent.clientHeight); }
|
|
80
|
+
}
|
|
81
|
+
left = Math.max(0, left); top = Math.max(0, top); right = Math.min(innerWidth, right); bottom = Math.min(innerHeight, bottom);
|
|
82
|
+
if (right <= left || bottom <= top || !element.getClientRects().length) return;
|
|
83
|
+
present.add(element);
|
|
84
|
+
let grid = scopedGrids.get(element);
|
|
85
|
+
if (!grid) { grid = document.createElement('div'); grid.className = 'grid'; grid.setAttribute('data-ds-grid-region', ''); shadow.append(grid); scopedGrids.set(element, grid); resize.observe(element); }
|
|
86
|
+
const style = getComputedStyle(element);
|
|
87
|
+
for (const property of ['--ds-grid-unit', '--unit', '--sf', '--ds-grid-color', '--ds-grid-origin-x', '--ds-grid-origin-y', '--ds-grid-line-offset']) {
|
|
88
|
+
const value = style.getPropertyValue(property); if (value) grid.style.setProperty(property, value); else grid.style.removeProperty(property);
|
|
89
|
+
}
|
|
90
|
+
Object.assign(grid.style, { inset: 'auto', left: `${left}px`, top: `${top}px`, width: `${right - left}px`, height: `${bottom - top}px` });
|
|
91
|
+
grid.style.setProperty('--ds-grid-scroll-x', `${window.scrollX + left + element.scrollLeft}px`);
|
|
92
|
+
grid.style.setProperty('--ds-grid-scroll-y', `${window.scrollY + top + element.scrollTop}px`);
|
|
93
|
+
// Opposite winding makes each viewport a hole in the page grid.
|
|
94
|
+
holes.push(`M${left},${top}V${bottom}H${right}V${top}Z`);
|
|
95
|
+
});
|
|
96
|
+
scopedGrids.forEach((grid, element) => { if (!present.has(element)) { resize.unobserve(element); grid.remove(); scopedGrids.delete(element); } });
|
|
97
|
+
pageGrid.style.clipPath = holes.length ? `path("M0,0H${innerWidth}V${innerHeight}H0Z ${holes.join(' ')}")` : '';
|
|
50
98
|
};
|
|
51
99
|
const setVisible = (visible: boolean) => {
|
|
52
100
|
overlay.hidden = !visible;
|
|
53
101
|
root.toggleAttribute("data-ds-grid-visible", visible);
|
|
54
102
|
if (visible) {
|
|
103
|
+
tracking = true;
|
|
55
104
|
updatePosition();
|
|
56
|
-
|
|
105
|
+
document.addEventListener('scroll', updatePosition, { passive: true, capture: true });
|
|
106
|
+
window.addEventListener('scroll', updatePosition, { passive: true });
|
|
107
|
+
window.addEventListener('resize', updatePosition, { passive: true });
|
|
108
|
+
regionsChanged.observe(document.body, { childList: true, subtree: true });
|
|
57
109
|
} else {
|
|
58
|
-
|
|
110
|
+
tracking = false;
|
|
111
|
+
document.removeEventListener('scroll', updatePosition, true);
|
|
112
|
+
window.removeEventListener('scroll', updatePosition);
|
|
113
|
+
window.removeEventListener('resize', updatePosition);
|
|
114
|
+
regionsChanged.disconnect(); resize.disconnect();
|
|
115
|
+
scopedGrids.forEach(grid => grid.remove()); scopedGrids.clear(); pageGrid.style.clipPath = '';
|
|
59
116
|
}
|
|
60
117
|
window.dispatchEvent(new CustomEvent("design-system-grid-changed", { detail: { visible } }));
|
|
61
118
|
};
|
|
@@ -128,7 +185,7 @@ export function initGridShortcut(): void {
|
|
|
128
185
|
presses = key === lastKey && now - lastPress <= 800 ? presses + 1 : 1;
|
|
129
186
|
lastKey = key;
|
|
130
187
|
lastPress = now;
|
|
131
|
-
if (presses ===
|
|
188
|
+
if (presses === GRID_PRESSES) {
|
|
132
189
|
reset();
|
|
133
190
|
if (key === 'g') setVisible(overlay.hidden !== false);
|
|
134
191
|
else layout.toggle();
|
package/DS1/0-face/i18n.ts
CHANGED
|
@@ -846,17 +846,46 @@ export function loadSharedWords(): Promise<void> {
|
|
|
846
846
|
return sharedWordsLoad;
|
|
847
847
|
}
|
|
848
848
|
|
|
849
|
+
/**
|
|
850
|
+
* The words a page loads as it starts (the shared words, the translations file), announced once
|
|
851
|
+
* between them: each announcement redraws every translated word on the page, so three arrivals in
|
|
852
|
+
* the first half second used to redraw it three times. A load that never ends holds the
|
|
853
|
+
* announcement back no longer than `STARTUP_WAIT`.
|
|
854
|
+
*/
|
|
855
|
+
const startupLoads: Promise<unknown>[] = [];
|
|
856
|
+
const STARTUP_WAIT = 1000;
|
|
857
|
+
let announcement: Promise<void> | null = null;
|
|
858
|
+
let announced = false;
|
|
859
|
+
/** The window this module loaded into, which hears its announcements. */
|
|
860
|
+
const page: Window | undefined = typeof window !== "undefined" ? window : undefined;
|
|
861
|
+
|
|
862
|
+
function announceTranslations(): void {
|
|
863
|
+
if (announcement) return;
|
|
864
|
+
const wait = new Promise<void>((resolve) => setTimeout(resolve, STARTUP_WAIT));
|
|
865
|
+
announcement = Promise.race([Promise.allSettled(startupLoads.splice(0)), wait]).then(() => {
|
|
866
|
+
announcement = null;
|
|
867
|
+
announced = true;
|
|
868
|
+
if (!eventful() || !page) return;
|
|
869
|
+
page.dispatchEvent(new CustomEvent("translations-loaded"));
|
|
870
|
+
// Dispatch language-changed to update all components
|
|
871
|
+
dispatchLanguageChanged(currentLanguage.value);
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
|
|
849
875
|
applyRouting();
|
|
850
876
|
if (i18nOptions.sharedWords) {
|
|
851
|
-
|
|
877
|
+
startupLoads.push(loadSharedWords());
|
|
852
878
|
}
|
|
853
879
|
|
|
854
880
|
// Auto-load translations when this module is imported (for CDN bundle).
|
|
855
881
|
// Waits a task, so a product can configure the module first, even after a
|
|
856
882
|
// dynamic import.
|
|
857
883
|
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
884
|
+
let started: () => void = () => {};
|
|
885
|
+
startupLoads.push(new Promise<void>((resolve) => (started = resolve)));
|
|
858
886
|
const start = () => {
|
|
859
|
-
if (i18nOptions.autoLoad !== false) void loadExternalTranslations();
|
|
887
|
+
if (i18nOptions.autoLoad !== false) void loadExternalTranslations().finally(started);
|
|
888
|
+
else started();
|
|
860
889
|
};
|
|
861
890
|
if (document.readyState === "loading") {
|
|
862
891
|
document.addEventListener("DOMContentLoaded", start);
|
|
@@ -871,24 +900,13 @@ if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
|
871
900
|
// below would otherwise throw after the code that imported this has finished.
|
|
872
901
|
const eventful = () => typeof window !== "undefined" && typeof window.addEventListener === "function" && typeof window.dispatchEvent === "function";
|
|
873
902
|
if (eventful()) {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
window.dispatchEvent(new CustomEvent("translations-loaded"));
|
|
903
|
+
// New words: translations-loaded and language-changed, once for everything still arriving.
|
|
904
|
+
window.addEventListener("translations-ready", announceTranslations);
|
|
877
905
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
});
|
|
881
|
-
|
|
882
|
-
// Initialize translations on module load
|
|
883
|
-
// Use setTimeout to give other parts of the app time to set up event listeners first
|
|
906
|
+
// A page whose words were all there at once still hears translations-loaded once, after its
|
|
907
|
+
// listeners have had a moment to attach; one already announced or on its way is enough.
|
|
884
908
|
setTimeout(() => {
|
|
885
|
-
if (
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
window.dispatchEvent(new CustomEvent("translations-loaded"));
|
|
889
|
-
|
|
890
|
-
// Also dispatch language-changed with the current language
|
|
891
|
-
dispatchLanguageChanged(currentLanguage.value);
|
|
909
|
+
if (eventful() && !announced && window === page) announceTranslations();
|
|
892
910
|
}, 100);
|
|
893
911
|
}
|
|
894
912
|
|