@charcoal-ui/react 6.0.0-rc.4 → 6.0.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/_lib/useIsomorphicLayoutEffect.d.ts +6 -0
  2. package/dist/_lib/useIsomorphicLayoutEffect.d.ts.map +1 -0
  3. package/dist/components/Carousel/index.d.ts +2 -6
  4. package/dist/components/Carousel/index.d.ts.map +1 -1
  5. package/dist/components/Carousel/useCarouselScroller.d.ts.map +1 -1
  6. package/dist/components/Modal/index.d.ts.map +1 -1
  7. package/dist/components/Modal/useTransitionPresence.d.ts +19 -0
  8. package/dist/components/Modal/useTransitionPresence.d.ts.map +1 -0
  9. package/dist/index.cjs +2 -2
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.css +124 -49
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/layered.css +124 -49
  17. package/dist/layered.css.map +1 -1
  18. package/package.json +5 -6
  19. package/src/__tests__/token-v1-compat.test.ts +0 -1
  20. package/src/_lib/useIsomorphicLayoutEffect.ts +7 -0
  21. package/src/components/Carousel/MIGRATION.md +39 -39
  22. package/src/components/Carousel/__snapshots__/index.css.snap +63 -39
  23. package/src/components/Carousel/index.browser.test.tsx +102 -0
  24. package/src/components/Carousel/index.css +68 -46
  25. package/src/components/Carousel/index.story.tsx +87 -68
  26. package/src/components/Carousel/index.test.tsx +120 -47
  27. package/src/components/Carousel/index.tsx +30 -14
  28. package/src/components/Carousel/useCarouselScroller.ts +8 -12
  29. package/src/components/FieldLabel/__snapshots__/index.css.snap +1 -1
  30. package/src/components/FieldLabel/index.css +1 -1
  31. package/src/components/IconButton/__snapshots__/index.css.snap +1 -1
  32. package/src/components/IconButton/index.css +1 -1
  33. package/src/components/Modal/__snapshots__/index.css.snap +32 -1
  34. package/src/components/Modal/index.css +34 -0
  35. package/src/components/Modal/index.test.tsx +200 -0
  36. package/src/components/Modal/index.tsx +48 -78
  37. package/src/components/Modal/useTransitionPresence.ts +95 -0
  38. package/src/index.ts +0 -1
package/dist/layered.css CHANGED
@@ -251,7 +251,7 @@
251
251
 
252
252
  .charcoal-icon-button[data-variant='Default'] {
253
253
  color: var(--charcoal-color-icon-tertiary-default);
254
- background-color: var(--charcoal-color-container-default-a);
254
+ background-color: transparent;
255
255
  }
256
256
 
257
257
  .charcoal-icon-button[data-variant='Default'][data-active='true']:not(:disabled):not([aria-disabled]),
@@ -810,7 +810,7 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
810
810
  line-height: 22px;
811
811
  font-weight: bold;
812
812
  display: flow-root;
813
- color: var(--charcoal-color-text-default);
813
+ color: var(--charcoal-color-text-default-text1);
814
814
  }
815
815
 
816
816
  .charcoal-field-label-required-text {
@@ -1009,6 +1009,40 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1009
1009
  }
1010
1010
  }
1011
1011
 
1012
+ /* easeOutQuart。duration は useTransitionPresence の MODAL_TRANSITION_DURATION_MS と一致させること。
1013
+ transition は entering / exiting に限定し、開いたままテーマ切り替え等で
1014
+ 色や transform が変わってもアニメーションしないようにする */
1015
+ .charcoal-modal-background[data-animation] {
1016
+ overflow: hidden;
1017
+ }
1018
+
1019
+ .charcoal-modal-background[data-animation='entering'],
1020
+ .charcoal-modal-background[data-animation='exiting'] {
1021
+ transition: background-color 400ms cubic-bezier(0.25, 1, 0.5, 1);
1022
+ }
1023
+
1024
+ /* 閉じアニメーション中はクリックを下のページへ通す(transitionend が来ない環境で
1025
+ 透明なオーバーレイがタップを奪い続けるのも防ぐ) */
1026
+ .charcoal-modal-background[data-animation='exited'],
1027
+ .charcoal-modal-background[data-animation='exiting'] {
1028
+ background-color: transparent;
1029
+ pointer-events: none;
1030
+ }
1031
+
1032
+ .charcoal-modal-background[data-animation='entered'] {
1033
+ overflow: auto;
1034
+ }
1035
+
1036
+ .charcoal-modal-background[data-animation='entering'] > .charcoal-modal-dialog,
1037
+ .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
1038
+ transition: transform 400ms cubic-bezier(0.25, 1, 0.5, 1);
1039
+ }
1040
+
1041
+ .charcoal-modal-background[data-animation='exited'] > .charcoal-modal-dialog,
1042
+ .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
1043
+ transform: translateY(100%);
1044
+ }
1045
+
1012
1046
  .charcoal-modal-close-button {
1013
1047
  position: absolute;
1014
1048
  top: 8px;
@@ -1838,10 +1872,18 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1838
1872
  position: relative;
1839
1873
  }
1840
1874
 
1875
+ /* フォーカスリングは scroller ではなく viewport に描く。scroller に置くと
1876
+ hasGradient の mask(mask-clip: border-box)で外側の box-shadow ごと消えるため。 */
1877
+
1878
+ .charcoal-carousel__viewport[data-focus-visible] {
1879
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1880
+ }
1881
+
1882
+ /* スライド間隔は所有しない(sandbox 同様、利用者が children 側で注入する)。
1883
+ このコンポーネントの責務はスクロールと indicator / arrow によるページ送りのみ。 */
1841
1884
  .charcoal-carousel__scroller {
1842
1885
  position: relative;
1843
1886
  display: flex;
1844
- gap: 24px;
1845
1887
  overflow-x: auto;
1846
1888
  overflow-y: hidden;
1847
1889
  overscroll-behavior-x: contain;
@@ -1849,19 +1891,10 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1849
1891
  scrollbar-width: none;
1850
1892
  outline: none;
1851
1893
  }
1852
-
1853
1894
  .charcoal-carousel__scroller::-webkit-scrollbar {
1854
1895
  display: none;
1855
1896
  }
1856
1897
 
1857
- .charcoal-carousel__scroller[data-focus-visible] {
1858
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1859
- }
1860
-
1861
- .charcoal-carousel[data-size='S'] .charcoal-carousel__scroller {
1862
- gap: 0;
1863
- }
1864
-
1865
1898
  /* スクロールスナップ type は prop(scrollSnap.type)で scroller に出し分ける。
1866
1899
  align は基底 .charcoal-carousel__item の後(後述)に置く(no-descending-specificity 回避)。
1867
1900
  未指定時の既定(M=none / S=mandatory / align=center)は JS 側で data 属性に解決する。 */
@@ -1879,44 +1912,64 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1879
1912
  scroll-snap-type: x mandatory;
1880
1913
  }
1881
1914
 
1882
- /* グラデーション: はみ出してスクロール可能な側のみ、端のアイテムを背景色(白)へ
1883
- フェードさせる。mask による透過ではなく、72px の「背景色→透明」オーバーレイを
1884
- ビューポートに重ねて白で覆う。スクロール可能な側だけ data-can-prev/next で出し分ける。 */
1885
- .charcoal-carousel[data-has-gradient='true']
1886
- .charcoal-carousel__viewport::before,
1887
- .charcoal-carousel[data-has-gradient='true']
1888
- .charcoal-carousel__viewport::after {
1889
- content: '';
1890
- position: absolute;
1891
- top: 0;
1892
- bottom: 0;
1893
- width: 72px;
1894
- pointer-events: none;
1895
- opacity: 0;
1896
- transition: 0.2s opacity;
1897
- z-index: 1;
1898
- }
1899
-
1900
- .charcoal-carousel[data-has-gradient='true']
1901
- .charcoal-carousel__viewport::before {
1902
- left: 0;
1903
- background: linear-gradient(to right, #fff, transparent);
1904
- }
1905
-
1906
- .charcoal-carousel[data-has-gradient='true']
1907
- .charcoal-carousel__viewport::after {
1908
- right: 0;
1909
- background: linear-gradient(to left, #fff, transparent);
1915
+ /* グラデーション: mask で端のアイテム自体を透明へフェードさせる(下の背景色を
1916
+ 問わない)。mask の色はアルファとしてだけ効く(#000=表示 / transparent=透過)。
1917
+ 左フェード・右フェードの 2 レイヤーを intersect で合成し、はみ出して
1918
+ スクロール可能な側のみ data-can-prev/next で 72px のフェード帯を枠内に置く。
1919
+ 無効な側はフェード帯ごと枠外へスライドして隠す(mask-image と違い
1920
+ mask-position は補間可能なので、切替が 0.2s のフェードになる)。 */
1921
+ .charcoal-carousel[data-has-gradient='true'] .charcoal-carousel__scroller {
1922
+ -webkit-mask-image:
1923
+ linear-gradient(to right, transparent, #000 72px),
1924
+ linear-gradient(to left, transparent, #000 72px);
1925
+ mask-image:
1926
+ linear-gradient(to right, transparent, #000 72px),
1927
+ linear-gradient(to left, transparent, #000 72px);
1928
+ /* 枠外へ 72px スライドしても反対側の端が欠けないよう、レイヤー幅に 72px 足す */
1929
+ -webkit-mask-size: calc(100% + 72px) 100%;
1930
+ mask-size: calc(100% + 72px) 100%;
1931
+ -webkit-mask-repeat: no-repeat;
1932
+ mask-repeat: no-repeat;
1933
+ -webkit-mask-composite: source-in, xor;
1934
+ mask-composite: intersect;
1935
+ -webkit-mask-position:
1936
+ -72px 0,
1937
+ 0 0;
1938
+ mask-position:
1939
+ -72px 0,
1940
+ 0 0;
1941
+ /* 0.2s ease-in は react-sandbox の LeftGradient と同じ値 */
1942
+ transition: 0.2s ease-in mask-position;
1910
1943
  }
1911
1944
 
1912
1945
  .charcoal-carousel[data-has-gradient='true'][data-can-prev='true']
1913
- .charcoal-carousel__viewport::before {
1914
- opacity: 1;
1946
+ .charcoal-carousel__scroller {
1947
+ -webkit-mask-position:
1948
+ 0 0,
1949
+ 0 0;
1950
+ mask-position:
1951
+ 0 0,
1952
+ 0 0;
1915
1953
  }
1916
1954
 
1917
1955
  .charcoal-carousel[data-has-gradient='true'][data-can-next='true']
1918
- .charcoal-carousel__viewport::after {
1919
- opacity: 1;
1956
+ .charcoal-carousel__scroller {
1957
+ -webkit-mask-position:
1958
+ -72px 0,
1959
+ -72px 0;
1960
+ mask-position:
1961
+ -72px 0,
1962
+ -72px 0;
1963
+ }
1964
+
1965
+ .charcoal-carousel[data-has-gradient='true'][data-can-prev='true'][data-can-next='true']
1966
+ .charcoal-carousel__scroller {
1967
+ -webkit-mask-position:
1968
+ 0 0,
1969
+ -72px 0;
1970
+ mask-position:
1971
+ 0 0,
1972
+ -72px 0;
1920
1973
  }
1921
1974
 
1922
1975
  .charcoal-carousel__item {
@@ -1940,7 +1993,7 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1940
1993
 
1941
1994
  /* ── Navigation Buttons (charcoal IconButton, variant=Overlay size=S) ── */
1942
1995
 
1943
- /* マスクと同じ 72px 1fr 72px グリッド。各ボタンは 72px ゾーンの中央に置く。 */
1996
+ /* マスクの透過域と同じ 72px 1fr 72px グリッド。各ボタンは 72px ゾーンの中央に置く。 */
1944
1997
  .charcoal-carousel__navigation {
1945
1998
  position: absolute;
1946
1999
  inset: 0;
@@ -1948,8 +2001,8 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1948
2001
  display: grid;
1949
2002
  grid-template-columns: 72px 1fr 72px;
1950
2003
  align-items: center;
1951
- /* 白フェード(z-index: 1)より上にボタンを表示する */
1952
- z-index: 2;
2004
+ /* アイテム内のコンテンツより上にボタンを表示する */
2005
+ z-index: 1;
1953
2006
  /* sandbox 同様、通常は隠してカルーセル hover 時にフェードイン表示する。 */
1954
2007
  opacity: 0;
1955
2008
  transition: 0.4s opacity;
@@ -1958,9 +2011,11 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1958
2011
  display: none;
1959
2012
  }
1960
2013
 
1961
- /* hover で表示。キーボード操作でも到達できるよう focus-within でも表示する。 */
2014
+ /* hover で表示。キーボード操作でも到達できるよう、キーボード由来のフォーカスが
2015
+ カルーセル内にある間も表示する(:focus-within だとクリックで残ったフォーカスでも
2016
+ 表示され続けるため、react-aria が付与する data 属性で判定する)。 */
1962
2017
  .charcoal-carousel:hover .charcoal-carousel__navigation,
1963
- .charcoal-carousel:focus-within .charcoal-carousel__navigation {
2018
+ .charcoal-carousel[data-focus-visible-within] .charcoal-carousel__navigation {
1964
2019
  opacity: 1;
1965
2020
  }
1966
2021
 
@@ -1968,16 +2023,36 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1968
2023
  pointer-events: auto;
1969
2024
  }
1970
2025
 
2026
+ /* ヒットエリアをグリッド端列(= mask のフェード帯と同じ 72px)全体へ広げる。
2027
+ 擬似要素上のクリックは元の button に届くため、帯のどこを押してもページ送りになる。
2028
+ position: absolute の基準は positioned な .charcoal-carousel__navigation(inset: 0)。 */
2029
+
2030
+ .charcoal-carousel__navigation__item::after {
2031
+ content: '';
2032
+ position: absolute;
2033
+ top: 0;
2034
+ bottom: 0;
2035
+ width: 72px;
2036
+ }
2037
+
1971
2038
  .charcoal-carousel__navigation__item[data-direction='prev'] {
1972
2039
  grid-column: 1;
1973
2040
  justify-self: center;
1974
2041
  }
1975
2042
 
2043
+ .charcoal-carousel__navigation__item[data-direction='prev']::after {
2044
+ left: 0;
2045
+ }
2046
+
1976
2047
  .charcoal-carousel__navigation__item[data-direction='next'] {
1977
2048
  grid-column: 3;
1978
2049
  justify-self: center;
1979
2050
  }
1980
2051
 
2052
+ .charcoal-carousel__navigation__item[data-direction='next']::after {
2053
+ right: 0;
2054
+ }
2055
+
1981
2056
  /* スクロール端では非表示。IconButton の disabled スタイル(opacity:0.32)より
1982
2057
  高い詳細度で打ち消すため、ルートを前置する。 */
1983
2058
  .charcoal-carousel .charcoal-carousel__navigation__item[data-hidden='true'] {