@openameba/spindle-ui 0.28.0 → 0.29.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/Breadcrumb/BreadcrumbItem.mjs +7 -0
- package/Breadcrumb/BreadcrumbList.mjs +12 -0
- package/Breadcrumb/index.mjs +2 -0
- package/Button/Button.mjs +7 -0
- package/Button/index.mjs +1 -0
- package/ButtonGroup/ButtonGroup.mjs +13 -0
- package/ButtonGroup/index.mjs +1 -0
- package/CHANGELOG.md +50 -0
- package/Form/Checkbox.mjs +11 -0
- package/Form/DropDown.mjs +38 -0
- package/Form/InlineDropDown.mjs +30 -0
- package/Form/InputLabel.mjs +5 -0
- package/Form/InvalidMessage.mjs +9 -0
- package/Form/Radio.mjs +11 -0
- package/Form/TextArea.mjs +5 -0
- package/Form/TextField.mjs +9 -0
- package/Form/ToggleSwitch.mjs +8 -0
- package/Form/index.mjs +8 -0
- package/HeroCarousel/HeroCarousel.mjs +27 -0
- package/HeroCarousel/HeroCarouselItem.mjs +20 -0
- package/HeroCarousel/hooks/useAutoPlayCarousel.mjs +158 -0
- package/HeroCarousel/hooks/useAutoSlide.mjs +40 -0
- package/HeroCarousel/hooks/useCarouselFocus.mjs +22 -0
- package/HeroCarousel/hooks/useSliderMoveEvent.mjs +47 -0
- package/HeroCarousel/hooks/useSliderTransition.mjs +30 -0
- package/HeroCarousel/hooks/useValueRef.mjs +8 -0
- package/HeroCarousel/index.mjs +1 -0
- package/Icon/755.mjs +4 -0
- package/Icon/Abemakun.mjs +4 -0
- package/Icon/Abematv.mjs +4 -0
- package/Icon/Accesslink.mjs +4 -0
- package/Icon/Accesspage.mjs +4 -0
- package/Icon/AccesspageFill.mjs +4 -0
- package/Icon/AddressbookFill.mjs +4 -0
- package/Icon/AlbumAddFill.mjs +4 -0
- package/Icon/AlbumFill.mjs +4 -0
- package/Icon/AlignCenter.mjs +4 -0
- package/Icon/AlignLeft.mjs +4 -0
- package/Icon/AlignRight.mjs +4 -0
- package/Icon/AllFill.mjs +4 -0
- package/Icon/Amebacoin.mjs +4 -0
- package/Icon/Amebapick.mjs +7 -0
- package/Icon/Amegold.mjs +4 -0
- package/Icon/Amember.mjs +4 -0
- package/Icon/ArrowDown.mjs +4 -0
- package/Icon/ArrowDownBold.mjs +4 -0
- package/Icon/ArrowLeft.mjs +4 -0
- package/Icon/ArrowLeftBold.mjs +4 -0
- package/Icon/ArrowRight.mjs +4 -0
- package/Icon/ArrowRightBold.mjs +4 -0
- package/Icon/ArrowRightCircle.mjs +4 -0
- package/Icon/ArrowRightCircleFill.mjs +4 -0
- package/Icon/ArrowUp.mjs +4 -0
- package/Icon/ArrowUpBold.mjs +4 -0
- package/Icon/ArrowpagingDown.mjs +4 -0
- package/Icon/ArrowpagingDownCircle.mjs +4 -0
- package/Icon/ArrowpagingLeft.mjs +4 -0
- package/Icon/ArrowpagingLeftCircle.mjs +4 -0
- package/Icon/ArrowpagingRight.mjs +4 -0
- package/Icon/ArrowpagingRightCircle.mjs +4 -0
- package/Icon/ArrowpagingUp.mjs +4 -0
- package/Icon/ArrowpagingUpCircle.mjs +4 -0
- package/Icon/Article.mjs +4 -0
- package/Icon/ArticleSlash.mjs +4 -0
- package/Icon/Articledesign.mjs +4 -0
- package/Icon/Astrogy.mjs +4 -0
- package/Icon/AstrogyFill.mjs +4 -0
- package/Icon/Baby.mjs +5 -0
- package/Icon/Bbs.mjs +4 -0
- package/Icon/Beginner.mjs +4 -0
- package/Icon/Bell.mjs +4 -0
- package/Icon/BellFill.mjs +4 -0
- package/Icon/BellFillSlash.mjs +4 -0
- package/Icon/BellSlash.mjs +4 -0
- package/Icon/Blog.mjs +4 -0
- package/Icon/Bold.mjs +4 -0
- package/Icon/Book.mjs +4 -0
- package/Icon/BookFill.mjs +4 -0
- package/Icon/Bookmark.mjs +4 -0
- package/Icon/BookmarkFill.mjs +4 -0
- package/Icon/Bookshelf.mjs +4 -0
- package/Icon/BookshelfFill.mjs +4 -0
- package/Icon/Border.mjs +4 -0
- package/Icon/BottomnavFollowfeedActive.mjs +4 -0
- package/Icon/BottomnavFollowfeedInactive.mjs +4 -0
- package/Icon/BottomnavHomeActive.mjs +4 -0
- package/Icon/BottomnavHomeInactive.mjs +4 -0
- package/Icon/BottomnavMypageActive.mjs +4 -0
- package/Icon/BottomnavSearchActive.mjs +4 -0
- package/Icon/BottomnavSearchInactive.mjs +4 -0
- package/Icon/BottomnvavMypageInactive.mjs +4 -0
- package/Icon/Bullets.mjs +4 -0
- package/Icon/Calendar.mjs +4 -0
- package/Icon/CameraFill.mjs +4 -0
- package/Icon/CautionFill.mjs +4 -0
- package/Icon/Check.mjs +4 -0
- package/Icon/CheckBold.mjs +4 -0
- package/Icon/CheckCircle.mjs +4 -0
- package/Icon/CheckCircleFill.mjs +4 -0
- package/Icon/CheckRectangle.mjs +4 -0
- package/Icon/Checklist.mjs +4 -0
- package/Icon/ChevronDown.mjs +4 -0
- package/Icon/ChevronDownBold.mjs +4 -0
- package/Icon/ChevronLeft.mjs +4 -0
- package/Icon/ChevronLeftBold.mjs +4 -0
- package/Icon/ChevronRight.mjs +4 -0
- package/Icon/ChevronRightBold.mjs +4 -0
- package/Icon/ChevronUp.mjs +4 -0
- package/Icon/ChevronUpBold.mjs +4 -0
- package/Icon/Circle.mjs +4 -0
- package/Icon/CircleBold.mjs +4 -0
- package/Icon/CircleFill.mjs +4 -0
- package/Icon/CircleSlash.mjs +4 -0
- package/Icon/Clock.mjs +4 -0
- package/Icon/ClockFill.mjs +4 -0
- package/Icon/Coin.mjs +4 -0
- package/Icon/Comment.mjs +4 -0
- package/Icon/CommentFill.mjs +4 -0
- package/Icon/CommentPen.mjs +4 -0
- package/Icon/CommentTwoFill.mjs +4 -0
- package/Icon/CommentTwoSlashFill.mjs +4 -0
- package/Icon/Community.mjs +4 -0
- package/Icon/Compass.mjs +5 -0
- package/Icon/Coupon.mjs +4 -0
- package/Icon/Crop.mjs +4 -0
- package/Icon/CropDin.mjs +4 -0
- package/Icon/CropLandscape.mjs +4 -0
- package/Icon/Cross.mjs +4 -0
- package/Icon/CrossBold.mjs +4 -0
- package/Icon/CrossCircle.mjs +4 -0
- package/Icon/CrossCircleFill.mjs +4 -0
- package/Icon/CrossRectangle.mjs +4 -0
- package/Icon/Cutlery.mjs +4 -0
- package/Icon/DiamondTwo.mjs +9 -0
- package/Icon/Dice.mjs +5 -0
- package/Icon/Dot.mjs +4 -0
- package/Icon/Dotmoney.mjs +4 -0
- package/Icon/Download.mjs +4 -0
- package/Icon/Embed.mjs +4 -0
- package/Icon/EmotionFill.mjs +4 -0
- package/Icon/EntryLost.mjs +4 -0
- package/Icon/Exclamationmark.mjs +4 -0
- package/Icon/ExclamationmarkBalloon.mjs +4 -0
- package/Icon/ExclamationmarkBalloonFill.mjs +4 -0
- package/Icon/ExclamationmarkBold.mjs +4 -0
- package/Icon/ExclamationmarkCircle.mjs +4 -0
- package/Icon/ExclamationmarkCircleFill.mjs +4 -0
- package/Icon/Expand.mjs +4 -0
- package/Icon/ExpandExit.mjs +4 -0
- package/Icon/FaceUnhappy.mjs +5 -0
- package/Icon/Facebook.mjs +4 -0
- package/Icon/File.mjs +4 -0
- package/Icon/FileAdd.mjs +4 -0
- package/Icon/FileAddFill.mjs +4 -0
- package/Icon/FileCircle.mjs +4 -0
- package/Icon/FileCircleFill.mjs +4 -0
- package/Icon/FileFill.mjs +4 -0
- package/Icon/Filter.mjs +4 -0
- package/Icon/FilterCheck.mjs +4 -0
- package/Icon/Fit.mjs +4 -0
- package/Icon/FlagFill.mjs +4 -0
- package/Icon/FlagRanking.mjs +4 -0
- package/Icon/FlagRankingTrim.mjs +8 -0
- package/Icon/Flash.mjs +4 -0
- package/Icon/FlashAuto.mjs +4 -0
- package/Icon/FlashOff.mjs +4 -0
- package/Icon/Flowervase.mjs +4 -0
- package/Icon/Folder.mjs +4 -0
- package/Icon/FolderFill.mjs +4 -0
- package/Icon/FolderTwo.mjs +4 -0
- package/Icon/FolderTwoFill.mjs +4 -0
- package/Icon/Font.mjs +4 -0
- package/Icon/Fontstyle.mjs +4 -0
- package/Icon/Game.mjs +4 -0
- package/Icon/GameFill.mjs +4 -0
- package/Icon/GameKantan.mjs +4 -0
- package/Icon/Gear.mjs +4 -0
- package/Icon/GearFill.mjs +4 -0
- package/Icon/Genre.mjs +4 -0
- package/Icon/GenreAdd.mjs +4 -0
- package/Icon/GenreDone.mjs +4 -0
- package/Icon/GraphBar.mjs +4 -0
- package/Icon/Gruppo.mjs +4 -0
- package/Icon/HandWaveFill.mjs +4 -0
- package/Icon/Hatenabookmark.mjs +4 -0
- package/Icon/Heart.mjs +4 -0
- package/Icon/HeartFill.mjs +4 -0
- package/Icon/History.mjs +4 -0
- package/Icon/HomeFill.mjs +4 -0
- package/Icon/Hot.mjs +4 -0
- package/Icon/Htmltag.mjs +4 -0
- package/Icon/ImageAddFill.mjs +4 -0
- package/Icon/ImageBanFill.mjs +4 -0
- package/Icon/ImageFill.mjs +4 -0
- package/Icon/ImageFillSlash.mjs +4 -0
- package/Icon/ImageQuestionFill.mjs +4 -0
- package/Icon/Information.mjs +4 -0
- package/Icon/Instagram.mjs +4 -0
- package/Icon/Italic.mjs +4 -0
- package/Icon/Kaomoji.mjs +4 -0
- package/Icon/Keyboard.mjs +4 -0
- package/Icon/KeyboardDownFill.mjs +4 -0
- package/Icon/KeyboardFill.mjs +4 -0
- package/Icon/Koeblog.mjs +4 -0
- package/Icon/LineCircle.mjs +4 -0
- package/Icon/LineSquare.mjs +4 -0
- package/Icon/Link.mjs +4 -0
- package/Icon/ListBulleted.mjs +4 -0
- package/Icon/ListNumbered.mjs +4 -0
- package/Icon/Loading.mjs +4 -0
- package/Icon/LockFill.mjs +4 -0
- package/Icon/LockOpenFill.mjs +4 -0
- package/Icon/Magicwand.mjs +4 -0
- package/Icon/Mail.mjs +4 -0
- package/Icon/MailCheck.mjs +4 -0
- package/Icon/MailCircle.mjs +4 -0
- package/Icon/MailCircleFill.mjs +4 -0
- package/Icon/MailFill.mjs +4 -0
- package/Icon/Megaphone.mjs +4 -0
- package/Icon/MenuHamburger.mjs +4 -0
- package/Icon/MenuHamburgerBold.mjs +4 -0
- package/Icon/MenuHamburgerFourline.mjs +4 -0
- package/Icon/MenuHorizotal.mjs +4 -0
- package/Icon/MenuVertical.mjs +4 -0
- package/Icon/Messageboard.mjs +4 -0
- package/Icon/Microphone.mjs +4 -0
- package/Icon/MicrophoneFill.mjs +4 -0
- package/Icon/Minus.mjs +4 -0
- package/Icon/MinusBold.mjs +4 -0
- package/Icon/Moon.mjs +4 -0
- package/Icon/MoonFill.mjs +4 -0
- package/Icon/MovieCameraFill.mjs +4 -0
- package/Icon/MoviePlay.mjs +4 -0
- package/Icon/MoviePlayFill.mjs +4 -0
- package/Icon/MovieStop.mjs +4 -0
- package/Icon/MusicFill.mjs +4 -0
- package/Icon/New.mjs +4 -0
- package/Icon/Newbook.mjs +4 -0
- package/Icon/NewbookFill.mjs +4 -0
- package/Icon/News.mjs +4 -0
- package/Icon/Nice.mjs +4 -0
- package/Icon/NiceDone.mjs +4 -0
- package/Icon/Nodate.mjs +4 -0
- package/Icon/Now.mjs +4 -0
- package/Icon/Officialstar.mjs +4 -0
- package/Icon/OfficialstarFill.mjs +4 -0
- package/Icon/OnedariFill.mjs +4 -0
- package/Icon/OpenCl.mjs +4 -0
- package/Icon/Openblank.mjs +4 -0
- package/Icon/OpenblankFill.mjs +4 -0
- package/Icon/Ownd.mjs +4 -0
- package/Icon/PaletteFill.mjs +4 -0
- package/Icon/Pause.mjs +4 -0
- package/Icon/PauseBold.mjs +4 -0
- package/Icon/Pawprint.mjs +4 -0
- package/Icon/Pencil.mjs +4 -0
- package/Icon/PencilAdd.mjs +4 -0
- package/Icon/PencilBold.mjs +4 -0
- package/Icon/Person.mjs +4 -0
- package/Icon/PersonFill.mjs +4 -0
- package/Icon/PersonThreeFill.mjs +4 -0
- package/Icon/PersonTwoAddFill.mjs +4 -0
- package/Icon/PersonTwoDeleteFill.mjs +4 -0
- package/Icon/PersonTwoDoneFill.mjs +4 -0
- package/Icon/PersonTwoFill.mjs +4 -0
- package/Icon/Peta.mjs +4 -0
- package/Icon/Pigg.mjs +4 -0
- package/Icon/PinFill.mjs +4 -0
- package/Icon/PlayCircle.mjs +4 -0
- package/Icon/PlayFill.mjs +4 -0
- package/Icon/Plus.mjs +4 -0
- package/Icon/PlusBold.mjs +4 -0
- package/Icon/PlusCircle.mjs +4 -0
- package/Icon/PlusCircleFill.mjs +4 -0
- package/Icon/PremiumFill.mjs +4 -0
- package/Icon/Present.mjs +4 -0
- package/Icon/Profilecard.mjs +4 -0
- package/Icon/Qr.mjs +4 -0
- package/Icon/Question.mjs +4 -0
- package/Icon/QuestionmarkCircle.mjs +4 -0
- package/Icon/QuestionmarkCircleFill.mjs +4 -0
- package/Icon/RankingCrown.mjs +4 -0
- package/Icon/RankingCrownFill.mjs +4 -0
- package/Icon/RankingPlatformFill.mjs +4 -0
- package/Icon/Reblog.mjs +4 -0
- package/Icon/ReblogSlash.mjs +4 -0
- package/Icon/Redo.mjs +4 -0
- package/Icon/RedoBold.mjs +4 -0
- package/Icon/Refresh.mjs +4 -0
- package/Icon/ReplyCircleFill.mjs +4 -0
- package/Icon/ReplyFill.mjs +4 -0
- package/Icon/Requ.mjs +4 -0
- package/Icon/Sad.mjs +4 -0
- package/Icon/Saveblog.mjs +4 -0
- package/Icon/ScreenFull.mjs +4 -0
- package/Icon/ScreenInline.mjs +4 -0
- package/Icon/Search.mjs +4 -0
- package/Icon/Service.mjs +4 -0
- package/Icon/Share.mjs +4 -0
- package/Icon/ShineFill.mjs +4 -0
- package/Icon/Shirt.mjs +4 -0
- package/Icon/SidefaceClose.mjs +4 -0
- package/Icon/SidefaceOpen.mjs +4 -0
- package/Icon/Smartphone.mjs +4 -0
- package/Icon/SmartphoneFill.mjs +4 -0
- package/Icon/Sort.mjs +4 -0
- package/Icon/SortFeed.mjs +4 -0
- package/Icon/SortTile.mjs +4 -0
- package/Icon/SpeakerOffFill.mjs +4 -0
- package/Icon/SpeakerOnFill.mjs +4 -0
- package/Icon/Sprout.mjs +4 -0
- package/Icon/Stampside.mjs +4 -0
- package/Icon/Star.mjs +4 -0
- package/Icon/StarCircleFill.mjs +4 -0
- package/Icon/StarFaceFill.mjs +4 -0
- package/Icon/StarFill.mjs +4 -0
- package/Icon/StopFill.mjs +4 -0
- package/Icon/Strikethrough.mjs +4 -0
- package/Icon/Sun.mjs +4 -0
- package/Icon/SunFill.mjs +4 -0
- package/Icon/Switching.mjs +4 -0
- package/Icon/SwitchingCamera.mjs +4 -0
- package/Icon/TagFill.mjs +4 -0
- package/Icon/TagOfficialFill.mjs +4 -0
- package/Icon/Thumbsup.mjs +4 -0
- package/Icon/ThumbsupFill.mjs +4 -0
- package/Icon/Title.mjs +4 -0
- package/Icon/TopbloggerRibbon.mjs +4 -0
- package/Icon/TranscriptOff.mjs +4 -0
- package/Icon/TranscriptOn.mjs +4 -0
- package/Icon/Transmission.mjs +4 -0
- package/Icon/Trashcan.mjs +4 -0
- package/Icon/Trend.mjs +4 -0
- package/Icon/TrendFill.mjs +4 -0
- package/Icon/TriangleDown.mjs +4 -0
- package/Icon/TriangleLeft.mjs +4 -0
- package/Icon/TriangleRight.mjs +4 -0
- package/Icon/TriangleUp.mjs +4 -0
- package/Icon/TrianglearrowDown.mjs +4 -0
- package/Icon/TrianglearrowDownright.mjs +4 -0
- package/Icon/TrianglearrowRight.mjs +4 -0
- package/Icon/TrianglearrowUp.mjs +4 -0
- package/Icon/TrianglearrowUpright.mjs +4 -0
- package/Icon/TriangleendLeft.mjs +4 -0
- package/Icon/TriangleendRight.mjs +4 -0
- package/Icon/TrophyFill.mjs +4 -0
- package/Icon/TvFill.mjs +4 -0
- package/Icon/Twitter.mjs +4 -0
- package/Icon/Underline.mjs +4 -0
- package/Icon/Undo.mjs +4 -0
- package/Icon/UndoBold.mjs +4 -0
- package/Icon/Wallet.mjs +4 -0
- package/Icon/Webview.mjs +4 -0
- package/Icon/Youtube.mjs +4 -0
- package/Icon/index.mjs +327 -0
- package/IconButton/IconButton.mjs +5 -0
- package/IconButton/index.mjs +1 -0
- package/LinkButton/LinkButton.mjs +7 -0
- package/LinkButton/index.mjs +1 -0
- package/README.md +3 -1
- package/Toast/Toast.mjs +67 -0
- package/Toast/index.mjs +1 -0
- package/index.mjs +11 -0
- package/package.json +11 -3
- package/tsconfig.cjs.json +10 -0
- package/tsconfig.esm.json +8 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
export const BreadcrumbItem = forwardRef(function Item({ children, current, ...rest }, ref) {
|
|
3
|
+
if (current) {
|
|
4
|
+
return (React.createElement("a", Object.assign({ ref: ref, "aria-current": "page" }, rest), children));
|
|
5
|
+
}
|
|
6
|
+
return (React.createElement("a", Object.assign({ ref: ref }, rest), children));
|
|
7
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ChevronRightBold from '../Icon/ChevronRightBold';
|
|
3
|
+
const BLOCK_NAME = 'spui-Breadcrumb';
|
|
4
|
+
export const BreadcrumbList = (props) => {
|
|
5
|
+
const { children, className, ...rest } = props;
|
|
6
|
+
return (React.createElement("nav", Object.assign({ "aria-label": "\u30D1\u30F3\u304F\u305A\u30EA\u30B9\u30C8", className: [BLOCK_NAME, className].join(' ').trim() }, rest),
|
|
7
|
+
React.createElement("ol", { className: `${BLOCK_NAME}-list` }, React.Children.map(children, (child) => {
|
|
8
|
+
return React.isValidElement(child) ? (React.createElement("li", { className: `${BLOCK_NAME}-item` },
|
|
9
|
+
child,
|
|
10
|
+
React.createElement(ChevronRightBold, { "aria-hidden": "true", className: `${BLOCK_NAME}-chevron` }))) : null;
|
|
11
|
+
}))));
|
|
12
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-Button';
|
|
3
|
+
export const Button = forwardRef(function Button({ children, layout = 'intrinsic', size = 'large', variant = 'contained', icon, ...rest }, ref) {
|
|
4
|
+
return (React.createElement("button", Object.assign({ className: `${BLOCK_NAME} ${BLOCK_NAME}--${layout} ${BLOCK_NAME}--${size} ${BLOCK_NAME}--${variant}`, ref: ref }, rest), icon ? (React.createElement(React.Fragment, null,
|
|
5
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon ${BLOCK_NAME}-icon--${size}` }, icon),
|
|
6
|
+
children)) : (children)));
|
|
7
|
+
});
|
package/Button/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Button } from './Button';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-ButtonGroup';
|
|
3
|
+
export const ButtonGroup = ({ children, className, direction = 'row', size = 'large', ...rest }) => {
|
|
4
|
+
const classnames = [
|
|
5
|
+
BLOCK_NAME,
|
|
6
|
+
`${BLOCK_NAME}--${direction}`,
|
|
7
|
+
`${BLOCK_NAME}--${size}`,
|
|
8
|
+
className,
|
|
9
|
+
]
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.join(' ');
|
|
12
|
+
return (React.createElement("div", Object.assign({ className: classnames }, rest), children));
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ButtonGroup } from './ButtonGroup';
|
package/CHANGELOG.md
CHANGED
|
@@ -3,12 +3,29 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.29.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.28.0...@openameba/spindle-ui@0.29.0) (2022-03-31)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **spindle-ui:** set side effect for css ([b171005](https://github.com/openameba/spindle/commit/b17100528232b3d2cc2664e12e6a2b3a8e54a7eb))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [0.28.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.27.1...@openameba/spindle-ui@0.28.0) (2022-03-31)
|
|
7
18
|
|
|
8
19
|
|
|
9
20
|
### Features
|
|
10
21
|
|
|
11
22
|
* **spindle-icons:** update icons ([1090484](https://github.com/openameba/spindle/commit/1090484fe176a51481868dccf86251dc8e418f26))
|
|
23
|
+
## [0.27.2-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.27.1...@openameba/spindle-ui@0.27.2-alpha.0) (2022-03-29)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* **spindle-ui:** set side effect for css ([1527f43](https://github.com/openameba/spindle/commit/1527f4383f15515b9a106e8adf6190a87dc7624d))
|
|
12
29
|
|
|
13
30
|
|
|
14
31
|
|
|
@@ -25,6 +42,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
25
42
|
|
|
26
43
|
|
|
27
44
|
|
|
45
|
+
## [0.27.1-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.27.0...@openameba/spindle-ui@0.27.1-alpha.0) (2022-03-18)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Bug Fixes
|
|
49
|
+
|
|
50
|
+
* **spindle-ui:** set side effect for css ([c70cd42](https://github.com/openameba/spindle/commit/c70cd42e91959e8fe921a992f2c26eac3f5e920f))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
28
56
|
# [0.27.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.26.3...@openameba/spindle-ui@0.27.0) (2022-03-18)
|
|
29
57
|
|
|
30
58
|
|
|
@@ -76,6 +104,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
76
104
|
|
|
77
105
|
* **spindle-ui:** add HeroCarousel component ([d7e0a53](https://github.com/openameba/spindle/commit/d7e0a5302cfca4d7600188098ef4dd224998e2bb))
|
|
78
106
|
|
|
107
|
+
## [0.25.2-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.25.1...@openameba/spindle-ui@0.25.2-alpha.0) (2021-12-09)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
### Bug Fixes
|
|
111
|
+
|
|
112
|
+
* **spindle-ui:** set side effect for css ([bdf0c9f](https://github.com/openameba/spindle/commit/bdf0c9ff79a69ad9dd2706dcfe96bd29559b373e))
|
|
113
|
+
|
|
79
114
|
|
|
80
115
|
|
|
81
116
|
|
|
@@ -136,12 +171,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
136
171
|
### Features
|
|
137
172
|
|
|
138
173
|
* **spindle-icons:** update icons ([39ce767](https://github.com/openameba/spindle/commit/39ce7673df4556ee3b9a6ea6dc62ad25236a6fc9))
|
|
174
|
+
## [0.22.1-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.22.0...@openameba/spindle-ui@0.22.1-alpha.0) (2021-09-06)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
### Bug Fixes
|
|
178
|
+
|
|
179
|
+
* **spindle-ui:** set side effect for css ([f26be31](https://github.com/openameba/spindle/commit/f26be31bf53ec73fbe00222773ba691809dae5d5))
|
|
139
180
|
|
|
140
181
|
|
|
141
182
|
|
|
142
183
|
|
|
143
184
|
|
|
144
185
|
# [0.22.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.21.2...@openameba/spindle-ui@0.22.0) (2021-09-06)
|
|
186
|
+
## [0.21.3-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.21.2...@openameba/spindle-ui@0.21.3-alpha.0) (2021-07-30)
|
|
145
187
|
|
|
146
188
|
|
|
147
189
|
### Bug Fixes
|
|
@@ -163,12 +205,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
163
205
|
### BREAKING CHANGES
|
|
164
206
|
|
|
165
207
|
* **spindle-icons,spindle-ui:** setting icon was renamed to gear
|
|
208
|
+
* **spindle-ui:** set side effect for css ([ec4e8f1](https://github.com/openameba/spindle/commit/ec4e8f143cd6769cc6b3d49534233a46eaf79b2d))
|
|
166
209
|
|
|
167
210
|
|
|
168
211
|
|
|
169
212
|
|
|
170
213
|
|
|
171
214
|
## [0.21.2](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.21.1...@openameba/spindle-ui@0.21.2) (2021-07-30)
|
|
215
|
+
## [0.21.2-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.21.1...@openameba/spindle-ui@0.21.2-alpha.0) (2021-07-28)
|
|
172
216
|
|
|
173
217
|
**Note:** Version bump only for package @openameba/spindle-ui
|
|
174
218
|
|
|
@@ -229,6 +273,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
229
273
|
### Features
|
|
230
274
|
|
|
231
275
|
* **spindle-icons:** update icons ([ae07c8e](https://github.com/openameba/spindle/commit/ae07c8eca4f33789c45b3c3d6a2e7f8f17c11e81))
|
|
276
|
+
## [0.18.1-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.18.0...@openameba/spindle-ui@0.18.1-alpha.0) (2021-06-11)
|
|
277
|
+
|
|
278
|
+
**Note:** Version bump only for package @openameba/spindle-ui
|
|
232
279
|
|
|
233
280
|
|
|
234
281
|
|
|
@@ -284,6 +331,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
284
331
|
### Bug Fixes
|
|
285
332
|
|
|
286
333
|
* **spindle-ui:** fix CSS variable name ([f76d2ee](https://github.com/openameba/spindle/commit/f76d2ee1840574a1247a20ea1ee212b85d99708e))
|
|
334
|
+
# [0.15.0-alpha.0](https://github.com/openameba/spindle/compare/@openameba/spindle-ui@0.14.0...@openameba/spindle-ui@0.15.0-alpha.0) (2021-03-15)
|
|
335
|
+
|
|
336
|
+
**Note:** Version bump only for package @openameba/spindle-ui
|
|
287
337
|
|
|
288
338
|
|
|
289
339
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { CheckBold } from '../Icon';
|
|
3
|
+
const BLOCK_NAME = 'spui-Checkbox';
|
|
4
|
+
export const Checkbox = forwardRef(function Checkbox({ children, ...rest }, ref) {
|
|
5
|
+
return (React.createElement("label", { className: `${BLOCK_NAME}-label` },
|
|
6
|
+
React.createElement("input", Object.assign({ className: `${BLOCK_NAME}-input`, ref: ref, type: "checkbox" }, rest)),
|
|
7
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon` },
|
|
8
|
+
React.createElement(CheckBold, { "aria-hidden": "true" })),
|
|
9
|
+
React.createElement("span", { className: `${BLOCK_NAME}-outline` }),
|
|
10
|
+
children && React.createElement("span", { className: `${BLOCK_NAME}-text` }, children)));
|
|
11
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import mergeRefs from 'react-merge-refs';
|
|
3
|
+
import { ChevronDownBold } from '../Icon';
|
|
4
|
+
const BLOCK_NAME = 'spui-DropDown';
|
|
5
|
+
export const DropDown = forwardRef(function DropDown({ children, hasError = false, onChange, ...rest }, ref) {
|
|
6
|
+
const selectEl = useRef(null);
|
|
7
|
+
const [text, setText] = useState('');
|
|
8
|
+
const [disabled, setDisabled] = useState(false);
|
|
9
|
+
const update = () => {
|
|
10
|
+
if (selectEl && selectEl.current) {
|
|
11
|
+
const selectedEl = selectEl.current.options[selectEl.current.selectedIndex];
|
|
12
|
+
const value = selectedEl.text;
|
|
13
|
+
const disabled = selectedEl.disabled;
|
|
14
|
+
setText(value);
|
|
15
|
+
setDisabled(disabled);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const handleChange = (event) => {
|
|
19
|
+
if (typeof onChange === 'function') {
|
|
20
|
+
onChange(event);
|
|
21
|
+
}
|
|
22
|
+
update();
|
|
23
|
+
};
|
|
24
|
+
// Update text once
|
|
25
|
+
useEffect(update, []);
|
|
26
|
+
return (React.createElement("label", { className: [
|
|
27
|
+
`${BLOCK_NAME}-label`,
|
|
28
|
+
!disabled ? 'is-active' : '',
|
|
29
|
+
hasError ? 'is-error' : '',
|
|
30
|
+
]
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(' ') },
|
|
33
|
+
React.createElement("span", { className: `${BLOCK_NAME}-visual` }, text),
|
|
34
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon` },
|
|
35
|
+
React.createElement(ChevronDownBold, { "aria-hidden": "true" })),
|
|
36
|
+
React.createElement("select", Object.assign({ className: `${BLOCK_NAME}-select`, ref: mergeRefs([selectEl, ref]), onChange: handleChange }, rest), children),
|
|
37
|
+
React.createElement("span", { className: `${BLOCK_NAME}-outline` })));
|
|
38
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import mergeRefs from 'react-merge-refs';
|
|
3
|
+
import { ChevronDownBold } from '../Icon';
|
|
4
|
+
const BLOCK_NAME = 'spui-InlineDropDown';
|
|
5
|
+
export const InlineDropDown = forwardRef(function InlineDropDown({ children, visualSize = 'medium', onChange, ...rest }, ref) {
|
|
6
|
+
const selectEl = useRef(null);
|
|
7
|
+
const [text, setText] = useState('');
|
|
8
|
+
const update = () => {
|
|
9
|
+
if (selectEl && selectEl.current) {
|
|
10
|
+
const selectedEl = selectEl.current.options[selectEl.current.selectedIndex];
|
|
11
|
+
const value = selectedEl.text;
|
|
12
|
+
setText(value);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const handleChange = (event) => {
|
|
16
|
+
if (typeof onChange === 'function') {
|
|
17
|
+
onChange(event);
|
|
18
|
+
}
|
|
19
|
+
update();
|
|
20
|
+
};
|
|
21
|
+
// Update text once
|
|
22
|
+
useEffect(update, []);
|
|
23
|
+
return (React.createElement("label", { className: [`${BLOCK_NAME}-label`].filter(Boolean).join(' ') },
|
|
24
|
+
React.createElement("span", { className: `${BLOCK_NAME}-visual` },
|
|
25
|
+
React.createElement("span", { className: `${BLOCK_NAME}-text ${BLOCK_NAME}-text--${visualSize}` }, text),
|
|
26
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon ${BLOCK_NAME}-icon--${visualSize}` },
|
|
27
|
+
React.createElement(ChevronDownBold, { "aria-hidden": "true" }))),
|
|
28
|
+
React.createElement("select", Object.assign({ className: `${BLOCK_NAME}-select ${BLOCK_NAME}-select--${visualSize}`, ref: mergeRefs([selectEl, ref]), onChange: handleChange }, rest), children),
|
|
29
|
+
React.createElement("span", { className: `${BLOCK_NAME}-outline` })));
|
|
30
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ExclamationmarkCircleFill } from '../Icon';
|
|
3
|
+
const BLOCK_NAME = 'spui-InvalidMessage';
|
|
4
|
+
export const InvalidMessage = ({ children, visible = false, ...rest }) => {
|
|
5
|
+
return (React.createElement("p", Object.assign({ className: BLOCK_NAME, hidden: !visible }, rest),
|
|
6
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon` },
|
|
7
|
+
React.createElement(ExclamationmarkCircleFill, { "aria-hidden": "true" })),
|
|
8
|
+
React.createElement("span", { className: `${BLOCK_NAME}-body` }, children)));
|
|
9
|
+
};
|
package/Form/Radio.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { CheckBold } from '../Icon';
|
|
3
|
+
const BLOCK_NAME = 'spui-Radio';
|
|
4
|
+
export const Radio = forwardRef(function Radio({ children, id = '', ...rest }, ref) {
|
|
5
|
+
return (React.createElement("label", { className: `${BLOCK_NAME}-label`, htmlFor: id },
|
|
6
|
+
React.createElement("input", Object.assign({ className: `${BLOCK_NAME}-input`, id: id, ref: ref, type: "radio" }, rest)),
|
|
7
|
+
React.createElement("span", { className: `${BLOCK_NAME}-icon` },
|
|
8
|
+
React.createElement(CheckBold, { "aria-hidden": "true" })),
|
|
9
|
+
React.createElement("span", { className: `${BLOCK_NAME}-outline` }),
|
|
10
|
+
children && React.createElement("span", { className: `${BLOCK_NAME}-text` }, children)));
|
|
11
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-TextArea';
|
|
3
|
+
export const TextArea = forwardRef(function TextArea({ children, hasError = false, id = '', ...rest }, ref) {
|
|
4
|
+
return (React.createElement("textarea", Object.assign({ className: [`${BLOCK_NAME}`, hasError ? 'is-error' : ''].join(' '), id: id, ref: ref }, rest), children));
|
|
5
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-TextField';
|
|
3
|
+
export const TextField = forwardRef(function TextField({ hasError = false, id = '', variant = 'medium', ...rest }, ref) {
|
|
4
|
+
return (React.createElement("input", Object.assign({ className: [
|
|
5
|
+
`${BLOCK_NAME}`,
|
|
6
|
+
`${BLOCK_NAME}--${variant}`,
|
|
7
|
+
hasError ? 'is-error' : '',
|
|
8
|
+
].join(' '), id: id, ref: ref }, rest)));
|
|
9
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-ToggleSwitch';
|
|
3
|
+
export const ToggleSwitch = forwardRef(function ToggleSwitch({ id = '', ...rest }, ref) {
|
|
4
|
+
return (React.createElement("label", { className: BLOCK_NAME },
|
|
5
|
+
React.createElement("input", Object.assign({ className: `${BLOCK_NAME}-input`, id: id, ref: ref, type: "checkbox" }, rest)),
|
|
6
|
+
React.createElement("span", { className: `${BLOCK_NAME}-visual` }),
|
|
7
|
+
React.createElement("span", { className: `${BLOCK_NAME}-outline` })));
|
|
8
|
+
});
|
package/Form/index.mjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Checkbox } from './Checkbox';
|
|
2
|
+
export { DropDown } from './DropDown';
|
|
3
|
+
export { InputLabel } from './InputLabel';
|
|
4
|
+
export { InvalidMessage } from './InvalidMessage';
|
|
5
|
+
export { Radio } from './Radio';
|
|
6
|
+
export { TextArea } from './TextArea';
|
|
7
|
+
export { TextField } from './TextField';
|
|
8
|
+
export { ToggleSwitch } from './ToggleSwitch';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ChevronLeftBold from '../Icon/ChevronLeftBold';
|
|
3
|
+
import ChevronRightBold from '../Icon/ChevronRightBold';
|
|
4
|
+
import Pause from '../Icon/Pause';
|
|
5
|
+
import PlayFill from '../Icon/PlayFill';
|
|
6
|
+
import HeroCarouselItem from './HeroCarouselItem';
|
|
7
|
+
import { useAutoPlayCarousel } from './hooks/useAutoPlayCarousel';
|
|
8
|
+
const BLOCK_NAME = 'spui-HeroCarousel';
|
|
9
|
+
const ITEM_LINK_CLASS_NAME = 'js-auto-play-carousel-item-link';
|
|
10
|
+
export const HeroCarousel = React.memo(function HeroCarousel({ carouselList, }) {
|
|
11
|
+
if (carouselList.length === 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const { handleSlideToPrev, handleSlideToNext, handleMouseEnter, handleMouseDown, handleMouseLeave, handleTouchStart, handleTransitionEnd, isAutoPlaying, isLinkClicked, itemsToRender, listRef, listStyles, toggleAutoPlay, handleFocus, handleBlur, } = useAutoPlayCarousel({
|
|
15
|
+
items: carouselList,
|
|
16
|
+
itemLinkClassName: ITEM_LINK_CLASS_NAME,
|
|
17
|
+
});
|
|
18
|
+
return (React.createElement("div", null,
|
|
19
|
+
React.createElement("div", { className: `${BLOCK_NAME}-container`, onBlur: handleBlur, onFocus: handleFocus, onMouseDown: handleMouseDown, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onTouchStart: handleTouchStart, onTransitionEnd: handleTransitionEnd },
|
|
20
|
+
React.createElement("ul", { "aria-roledescription": "\u30AB\u30EB\u30FC\u30BB\u30EB", className: `${BLOCK_NAME}-list`, ref: listRef, role: "group", style: listStyles }, itemsToRender.map((item, index) => (React.createElement(HeroCarouselItem, { carouselItem: item, isLinkClicked: isLinkClicked, itemLinkClassName: ITEM_LINK_CLASS_NAME, key: `hero-carousel-${index}` }))))),
|
|
21
|
+
React.createElement("div", { className: `${BLOCK_NAME}-controls` },
|
|
22
|
+
React.createElement("button", { "aria-label": "1\u3064\u524D\u306E\u30A2\u30A4\u30C6\u30E0\u306B\u79FB\u52D5", className: `${BLOCK_NAME}-control ${BLOCK_NAME}-control--prev`, type: "button", onClick: handleSlideToPrev },
|
|
23
|
+
React.createElement(ChevronLeftBold, { "aria-hidden": true })),
|
|
24
|
+
React.createElement("button", { "aria-label": isAutoPlaying ? 'スライドを停止' : 'スライドを再生', className: `${BLOCK_NAME}-control`, type: "button", onClick: toggleAutoPlay }, isAutoPlaying ? (React.createElement(Pause, { "aria-hidden": true })) : (React.createElement(PlayFill, { "aria-hidden": true }))),
|
|
25
|
+
React.createElement("button", { "aria-label": "1\u3064\u5F8C\u308D\u306E\u30A2\u30A4\u30C6\u30E0\u306B\u79FB\u52D5", className: `${BLOCK_NAME}-control ${BLOCK_NAME}-control--next`, type: "button", onClick: handleSlideToNext },
|
|
26
|
+
React.createElement(ChevronRightBold, { "aria-hidden": true })))));
|
|
27
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
const BLOCK_NAME = 'spui-HeroCarouselItem';
|
|
3
|
+
export const HeroCarouselItem = React.memo(function HeroCarouselItem({ carouselItem, isLinkClicked, itemLinkClassName, }) {
|
|
4
|
+
const handleLinkClick = useCallback((e) => {
|
|
5
|
+
if (!isLinkClicked) {
|
|
6
|
+
e.preventDefault();
|
|
7
|
+
}
|
|
8
|
+
}, [isLinkClicked]);
|
|
9
|
+
return (React.createElement("li", { className: `${BLOCK_NAME}-listItem` },
|
|
10
|
+
React.createElement("a", { className: `${itemLinkClassName} ${BLOCK_NAME}-link`, href: carouselItem.link, onClick: handleLinkClick },
|
|
11
|
+
React.createElement("span", { className: `${BLOCK_NAME}-imageBlock` },
|
|
12
|
+
React.createElement("img", { alt: "", className: `${BLOCK_NAME}-image`, src: carouselItem.imageUrl })),
|
|
13
|
+
React.createElement("div", { className: `${BLOCK_NAME}-titleContainer` },
|
|
14
|
+
React.createElement("p", { className: `${BLOCK_NAME}-title` }, carouselItem.title)))));
|
|
15
|
+
}, (prevProps, nextProps) => prevProps.isLinkClicked === nextProps.isLinkClicked &&
|
|
16
|
+
prevProps.itemLinkClassName === nextProps.itemLinkClassName &&
|
|
17
|
+
prevProps.carouselItem.title === nextProps.carouselItem.title &&
|
|
18
|
+
prevProps.carouselItem.link === nextProps.carouselItem.link &&
|
|
19
|
+
prevProps.carouselItem.imageUrl === nextProps.carouselItem.imageUrl);
|
|
20
|
+
export default HeroCarouselItem;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { useAutoSlide } from './useAutoSlide';
|
|
3
|
+
import { useCarouselFocus } from './useCarouselFocus';
|
|
4
|
+
import { useSliderMoveEvent } from './useSliderMoveEvent';
|
|
5
|
+
import { useSliderTransition } from './useSliderTransition';
|
|
6
|
+
import { useValueRef } from './useValueRef';
|
|
7
|
+
const COPY_COUNT = 5;
|
|
8
|
+
const SWIPE_THRESHOLD_X = 20;
|
|
9
|
+
export function useAutoPlayCarousel({ items, itemLinkClassName, }) {
|
|
10
|
+
const { diffXRef, diffYRef, setDiffX, setDiffY, setStartX, setStartY, } = useSliderMoveEvent();
|
|
11
|
+
const [focusOffset, setFocusOffset] = useState(0);
|
|
12
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
13
|
+
const [isLinkClicked, setIsLinkClicked] = useState(false);
|
|
14
|
+
const isHoveringRef = useValueRef(isHovering);
|
|
15
|
+
const slideToNextRef = useValueRef(() => slideToNext());
|
|
16
|
+
const itemCount = useMemo(() => items.length, [items]);
|
|
17
|
+
const getIsCopiedItem = useCallback((index) => {
|
|
18
|
+
return index < COPY_COUNT || index >= itemCount + COPY_COUNT;
|
|
19
|
+
}, [itemCount]);
|
|
20
|
+
const { isAutoPlaying, setIsAutoPlaying, resetAutoSlide, resetTimeOut, toggleAutoPlay, } = useAutoSlide({
|
|
21
|
+
onTimeOut: slideToNextRef.current,
|
|
22
|
+
});
|
|
23
|
+
const { linkRefs, listRef } = useCarouselFocus({
|
|
24
|
+
getIsCopiedItem,
|
|
25
|
+
itemLinkClassName,
|
|
26
|
+
});
|
|
27
|
+
const isAutoPlayingRef = useValueRef(isAutoPlaying);
|
|
28
|
+
const { currentIndexRef, handleTransitionEnd, listStyles, setCurrentIndex, setDisableAutoFocus, setDisableTransition, } = useSliderTransition({
|
|
29
|
+
copyCount: COPY_COUNT,
|
|
30
|
+
itemCount,
|
|
31
|
+
isAutoPlaying,
|
|
32
|
+
linkRefs,
|
|
33
|
+
});
|
|
34
|
+
const itemsToRender = useMemo(
|
|
35
|
+
// generate copy contents on both ends to make carousel look like looping
|
|
36
|
+
() => [
|
|
37
|
+
...items.slice(-COPY_COUNT),
|
|
38
|
+
...items,
|
|
39
|
+
...items.slice(0, COPY_COUNT),
|
|
40
|
+
], [items]);
|
|
41
|
+
const slideToNext = (ignoreHover = false) => {
|
|
42
|
+
const shouldSlideToNext = ((!isHoveringRef.current && isAutoPlayingRef.current) || ignoreHover) &&
|
|
43
|
+
currentIndexRef.current <= itemCount;
|
|
44
|
+
if (shouldSlideToNext) {
|
|
45
|
+
setDisableTransition(false);
|
|
46
|
+
setCurrentIndex(currentIndexRef.current + 1);
|
|
47
|
+
}
|
|
48
|
+
resetAutoSlide();
|
|
49
|
+
};
|
|
50
|
+
const slideToPrev = () => {
|
|
51
|
+
if (currentIndexRef.current >= 0) {
|
|
52
|
+
setDisableTransition(false);
|
|
53
|
+
setCurrentIndex(currentIndexRef.current - 1);
|
|
54
|
+
}
|
|
55
|
+
resetAutoSlide();
|
|
56
|
+
};
|
|
57
|
+
const handleMouseEnter = () => setIsHovering(true);
|
|
58
|
+
const handleMouseLeave = () => {
|
|
59
|
+
setIsHovering(false);
|
|
60
|
+
resetAutoSlide();
|
|
61
|
+
};
|
|
62
|
+
const handleMouseDown = (e) => {
|
|
63
|
+
resetTimeOut();
|
|
64
|
+
setStartX(e.clientX);
|
|
65
|
+
setStartY(e.clientY);
|
|
66
|
+
};
|
|
67
|
+
const onMouseUp = () => {
|
|
68
|
+
if (diffXRef.current > SWIPE_THRESHOLD_X) {
|
|
69
|
+
setIsLinkClicked(false);
|
|
70
|
+
setIsAutoPlaying(false);
|
|
71
|
+
slideToPrev();
|
|
72
|
+
}
|
|
73
|
+
if (diffXRef.current < -SWIPE_THRESHOLD_X) {
|
|
74
|
+
setIsLinkClicked(false);
|
|
75
|
+
setIsAutoPlaying(false);
|
|
76
|
+
slideToNext(true);
|
|
77
|
+
}
|
|
78
|
+
if (diffXRef.current === 0 && diffYRef.current === 0) {
|
|
79
|
+
setIsLinkClicked(true);
|
|
80
|
+
}
|
|
81
|
+
setStartX(null);
|
|
82
|
+
setStartY(null);
|
|
83
|
+
setDiffX(0);
|
|
84
|
+
setDiffY(0);
|
|
85
|
+
};
|
|
86
|
+
const handleTouchStart = (e) => {
|
|
87
|
+
if (!e.touches.length)
|
|
88
|
+
return;
|
|
89
|
+
const touch = e.touches[0];
|
|
90
|
+
resetTimeOut();
|
|
91
|
+
handleMouseEnter();
|
|
92
|
+
setStartX(touch.clientX);
|
|
93
|
+
setStartY(touch.clientY);
|
|
94
|
+
};
|
|
95
|
+
const onTouchEnd = () => {
|
|
96
|
+
setIsHovering(false);
|
|
97
|
+
onMouseUp();
|
|
98
|
+
};
|
|
99
|
+
const handleSlideToPrev = () => {
|
|
100
|
+
resetTimeOut();
|
|
101
|
+
setIsAutoPlaying(false);
|
|
102
|
+
slideToPrev();
|
|
103
|
+
};
|
|
104
|
+
const handleSlideToNext = () => {
|
|
105
|
+
resetTimeOut();
|
|
106
|
+
setIsAutoPlaying(false);
|
|
107
|
+
slideToNext(true);
|
|
108
|
+
};
|
|
109
|
+
const handleFocus = (e) => {
|
|
110
|
+
setIsAutoPlaying(false);
|
|
111
|
+
const { offsetLeft: newFocusOffset } = e.target;
|
|
112
|
+
setFocusOffset(newFocusOffset);
|
|
113
|
+
if (focusOffset === 0) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
setDisableAutoFocus(true);
|
|
117
|
+
if (isHovering && diffXRef.current === 0 && diffYRef.current === 0) {
|
|
118
|
+
setIsLinkClicked(true);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (focusOffset > newFocusOffset) {
|
|
122
|
+
setDisableTransition(false);
|
|
123
|
+
setCurrentIndex(currentIndexRef.current - 1);
|
|
124
|
+
}
|
|
125
|
+
if (focusOffset < newFocusOffset) {
|
|
126
|
+
setDisableTransition(false);
|
|
127
|
+
setCurrentIndex(currentIndexRef.current + 1);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const handleBlur = () => {
|
|
131
|
+
setIsAutoPlaying(true);
|
|
132
|
+
};
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
document.body.addEventListener('mouseup', onMouseUp);
|
|
135
|
+
document.body.addEventListener('touchend', onTouchEnd);
|
|
136
|
+
return () => {
|
|
137
|
+
document.body.removeEventListener('mouseup', onMouseUp);
|
|
138
|
+
document.body.removeEventListener('touchend', onTouchEnd);
|
|
139
|
+
};
|
|
140
|
+
}, []);
|
|
141
|
+
return {
|
|
142
|
+
handleSlideToPrev,
|
|
143
|
+
handleSlideToNext,
|
|
144
|
+
handleMouseEnter,
|
|
145
|
+
handleMouseDown,
|
|
146
|
+
handleMouseLeave,
|
|
147
|
+
handleTouchStart,
|
|
148
|
+
handleTransitionEnd,
|
|
149
|
+
isAutoPlaying,
|
|
150
|
+
isLinkClicked,
|
|
151
|
+
itemsToRender,
|
|
152
|
+
listRef,
|
|
153
|
+
listStyles,
|
|
154
|
+
toggleAutoPlay,
|
|
155
|
+
handleFocus,
|
|
156
|
+
handleBlur,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
const AUTO_SLIDE_SPEED = 4000; // ms
|
|
3
|
+
export function useAutoSlide({ onTimeOut }) {
|
|
4
|
+
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
|
|
5
|
+
const [timeoutId, setTimeoutId] = useState(null);
|
|
6
|
+
const resetTimeOut = useCallback(() => {
|
|
7
|
+
if (timeoutId) {
|
|
8
|
+
clearTimeout(timeoutId);
|
|
9
|
+
}
|
|
10
|
+
}, [timeoutId]);
|
|
11
|
+
const activateAutoSlide = () => {
|
|
12
|
+
resetTimeOut();
|
|
13
|
+
const newTimeoutId = setTimeout(() => {
|
|
14
|
+
onTimeOut();
|
|
15
|
+
}, AUTO_SLIDE_SPEED);
|
|
16
|
+
setTimeoutId(newTimeoutId);
|
|
17
|
+
};
|
|
18
|
+
const resetAutoSlide = () => {
|
|
19
|
+
if (isAutoPlaying) {
|
|
20
|
+
activateAutoSlide();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const toggleAutoPlay = () => {
|
|
24
|
+
resetTimeOut();
|
|
25
|
+
if (!isAutoPlaying) {
|
|
26
|
+
activateAutoSlide();
|
|
27
|
+
}
|
|
28
|
+
setIsAutoPlaying((prev) => !prev);
|
|
29
|
+
};
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
activateAutoSlide();
|
|
32
|
+
}, []);
|
|
33
|
+
return {
|
|
34
|
+
isAutoPlaying,
|
|
35
|
+
setIsAutoPlaying,
|
|
36
|
+
resetAutoSlide,
|
|
37
|
+
resetTimeOut,
|
|
38
|
+
toggleAutoPlay,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
export function useCarouselFocus({ getIsCopiedItem, itemLinkClassName, }) {
|
|
3
|
+
const listRef = useRef(null);
|
|
4
|
+
const linkRefs = useRef([]);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (!listRef.current)
|
|
7
|
+
return;
|
|
8
|
+
const linkElements = listRef.current.querySelectorAll(`a.${itemLinkClassName}`);
|
|
9
|
+
if (!linkElements)
|
|
10
|
+
return;
|
|
11
|
+
// NOTE: use NodeList forEach as IE polyfill
|
|
12
|
+
Array.prototype.forEach.call(linkElements, (link, index) => {
|
|
13
|
+
linkRefs.current.push(link);
|
|
14
|
+
link.setAttribute('tabindex', getIsCopiedItem(index) ? '-1' : '0');
|
|
15
|
+
link.setAttribute('aria-hidden', getIsCopiedItem(index) ? 'true' : 'false');
|
|
16
|
+
});
|
|
17
|
+
}, [getIsCopiedItem, itemLinkClassName]);
|
|
18
|
+
return {
|
|
19
|
+
linkRefs,
|
|
20
|
+
listRef,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useValueRef } from './useValueRef';
|
|
3
|
+
export function useSliderMoveEvent() {
|
|
4
|
+
const [diffX, setDiffX] = useState(0);
|
|
5
|
+
const [diffY, setDiffY] = useState(0);
|
|
6
|
+
const [startX, setStartX] = useState(null);
|
|
7
|
+
const [startY, setStartY] = useState(null);
|
|
8
|
+
const diffXRef = useValueRef(diffX);
|
|
9
|
+
const diffYRef = useValueRef(diffY);
|
|
10
|
+
const startXRef = useValueRef(startX);
|
|
11
|
+
const startYRef = useValueRef(startY);
|
|
12
|
+
const onMouseMove = (e) => {
|
|
13
|
+
if (startXRef.current === null || startYRef.current === null)
|
|
14
|
+
return;
|
|
15
|
+
e.preventDefault();
|
|
16
|
+
setDiffX(e.clientX - startXRef.current);
|
|
17
|
+
setDiffY(e.clientY - startYRef.current);
|
|
18
|
+
};
|
|
19
|
+
const onTouchMove = (e) => {
|
|
20
|
+
if (startXRef.current === null ||
|
|
21
|
+
startYRef.current === null ||
|
|
22
|
+
!e.touches.length) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const touch = e.touches[0];
|
|
26
|
+
setDiffX(touch.clientX - startXRef.current);
|
|
27
|
+
setDiffY(touch.clientY - startYRef.current);
|
|
28
|
+
};
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
document.body.addEventListener('mousemove', onMouseMove);
|
|
31
|
+
document.body.addEventListener('touchmove', onTouchMove, {
|
|
32
|
+
passive: true,
|
|
33
|
+
});
|
|
34
|
+
return () => {
|
|
35
|
+
document.body.removeEventListener('mousemove', onMouseMove);
|
|
36
|
+
document.body.removeEventListener('touchmove', onTouchMove);
|
|
37
|
+
};
|
|
38
|
+
}, []);
|
|
39
|
+
return {
|
|
40
|
+
diffXRef,
|
|
41
|
+
diffYRef,
|
|
42
|
+
setDiffX,
|
|
43
|
+
setDiffY,
|
|
44
|
+
setStartX,
|
|
45
|
+
setStartY,
|
|
46
|
+
};
|
|
47
|
+
}
|