@stevederico/skateboard-ui 2.23.0 → 3.0.1
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/.claude/worktrees/strange-feistel-abc494/App.jsx +179 -0
- package/.claude/worktrees/strange-feistel-abc494/CHANGELOG.md +687 -0
- package/.claude/worktrees/strange-feistel-abc494/MIGRATION.md +230 -0
- package/.claude/worktrees/strange-feistel-abc494/README.md +1252 -0
- package/.claude/worktrees/strange-feistel-abc494/components/AuthOverlay.jsx +74 -0
- package/.claude/worktrees/strange-feistel-abc494/components/ErrorBoundary.jsx +106 -0
- package/.claude/worktrees/strange-feistel-abc494/components/ProtectedRoute.jsx +66 -0
- package/.claude/worktrees/strange-feistel-abc494/components/Sheet.jsx +61 -0
- package/.claude/worktrees/strange-feistel-abc494/components/ThemeToggle.jsx +53 -0
- package/.claude/worktrees/strange-feistel-abc494/components/UpgradeSheet.jsx +127 -0
- package/.claude/worktrees/strange-feistel-abc494/components.json +21 -0
- package/.claude/worktrees/strange-feistel-abc494/core/Context.jsx +251 -0
- package/.claude/worktrees/strange-feistel-abc494/core/DynamicIcon.jsx +110 -0
- package/.claude/worktrees/strange-feistel-abc494/core/Utilities.js +1031 -0
- package/.claude/worktrees/strange-feistel-abc494/fonts/GeistMonoVF.woff2 +0 -0
- package/.claude/worktrees/strange-feistel-abc494/fonts/GeistVF.woff2 +0 -0
- package/.claude/worktrees/strange-feistel-abc494/hooks/useAuthGate.js +37 -0
- package/.claude/worktrees/strange-feistel-abc494/index.js +3 -0
- package/.claude/worktrees/strange-feistel-abc494/jsconfig.json +9 -0
- package/.claude/worktrees/strange-feistel-abc494/layout/Header.jsx +50 -0
- package/.claude/worktrees/strange-feistel-abc494/layout/Layout.jsx +60 -0
- package/.claude/worktrees/strange-feistel-abc494/layout/Sidebar.jsx +124 -0
- package/.claude/worktrees/strange-feistel-abc494/layout/TabBar.jsx +70 -0
- package/.claude/worktrees/strange-feistel-abc494/package.json +146 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/hooks/use-mobile.js +19 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/lib/utils.js +6 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/accordion.jsx +77 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/alert-dialog.jsx +172 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/alert.jsx +77 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/aspect-ratio.jsx +21 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/avatar.jsx +107 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/badge.jsx +45 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/breadcrumb.jsx +124 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/button-group.jsx +82 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/button.jsx +61 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/calendar.jsx +177 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/card.jsx +114 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/carousel.jsx +195 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/chart.jsx +312 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/checkbox.jsx +29 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/collapsible.jsx +21 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/command.jsx +178 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/context-menu.jsx +239 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/dialog.jsx +150 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/drawer.jsx +130 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/dropdown-menu.jsx +248 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/empty.jsx +110 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/field.jsx +229 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/hover-card.jsx +45 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/input-group.jsx +149 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/input.jsx +23 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/item.jsx +203 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/kbd.jsx +30 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/label.jsx +20 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/menubar.jsx +265 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/navigation-menu.jsx +159 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/pagination.jsx +122 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/popover.jsx +91 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/progress.jsx +82 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/radio-group.jsx +43 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/resizable.jsx +47 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/scroll-area.jsx +48 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/select.jsx +187 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/separator.jsx +24 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/sheet.jsx +140 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/sidebar.jsx +668 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/skeleton.jsx +15 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/slider.jsx +51 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/spinner.jsx +17 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/switch.jsx +26 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/table.jsx +123 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/tabs.jsx +79 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/textarea.jsx +20 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/toggle-group.jsx +75 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/toggle.jsx +43 -0
- package/.claude/worktrees/strange-feistel-abc494/shadcn/ui/tooltip.jsx +61 -0
- package/.claude/worktrees/strange-feistel-abc494/styles.css +300 -0
- package/.claude/worktrees/strange-feistel-abc494/views/LandingView.jsx +207 -0
- package/.claude/worktrees/strange-feistel-abc494/views/NotFound.jsx +27 -0
- package/.claude/worktrees/strange-feistel-abc494/views/PaymentView.jsx +118 -0
- package/.claude/worktrees/strange-feistel-abc494/views/SettingsView.jsx +199 -0
- package/.claude/worktrees/strange-feistel-abc494/views/SignInView.jsx +171 -0
- package/.claude/worktrees/strange-feistel-abc494/views/SignOutView.jsx +54 -0
- package/.claude/worktrees/strange-feistel-abc494/views/SignUpView.jsx +208 -0
- package/.claude/worktrees/strange-feistel-abc494/views/TextView.jsx +48 -0
- package/App.jsx +1 -3
- package/CHANGELOG.md +27 -0
- package/README.md +64 -2
- package/components/ThemeToggle.jsx +3 -3
- package/components/UpgradeSheet.jsx +1 -1
- package/core/Calendar.jsx +513 -0
- package/core/Command.jsx +203 -0
- package/core/DynamicIcon.jsx +2 -2
- package/core/ThemeProvider.jsx +77 -0
- package/icons/AArrowDown.jsx +12 -0
- package/icons/AArrowUp.jsx +12 -0
- package/icons/ALargeSmall.jsx +12 -0
- package/icons/Accessibility.jsx +13 -0
- package/icons/Activity.jsx +9 -0
- package/icons/AirVent.jsx +12 -0
- package/icons/Airplay.jsx +10 -0
- package/icons/AlarmClock.jsx +14 -0
- package/icons/AlarmClockCheck.jsx +14 -0
- package/icons/AlarmClockMinus.jsx +14 -0
- package/icons/AlarmClockOff.jsx +14 -0
- package/icons/AlarmClockPlus.jsx +15 -0
- package/icons/AlarmSmoke.jsx +13 -0
- package/icons/Album.jsx +10 -0
- package/icons/AlignCenterHorizontal.jsx +13 -0
- package/icons/AlignCenterVertical.jsx +13 -0
- package/icons/AlignEndHorizontal.jsx +11 -0
- package/icons/AlignEndVertical.jsx +11 -0
- package/icons/AlignHorizontalDistributeCenter.jsx +14 -0
- package/icons/AlignHorizontalDistributeEnd.jsx +12 -0
- package/icons/AlignHorizontalDistributeStart.jsx +12 -0
- package/icons/AlignHorizontalJustifyCenter.jsx +11 -0
- package/icons/AlignHorizontalJustifyEnd.jsx +11 -0
- package/icons/AlignHorizontalJustifyStart.jsx +11 -0
- package/icons/AlignHorizontalSpaceAround.jsx +11 -0
- package/icons/AlignHorizontalSpaceBetween.jsx +12 -0
- package/icons/AlignStartHorizontal.jsx +11 -0
- package/icons/AlignStartVertical.jsx +11 -0
- package/icons/AlignVerticalDistributeCenter.jsx +14 -0
- package/icons/AlignVerticalDistributeEnd.jsx +12 -0
- package/icons/AlignVerticalDistributeStart.jsx +12 -0
- package/icons/AlignVerticalJustifyCenter.jsx +11 -0
- package/icons/AlignVerticalJustifyEnd.jsx +11 -0
- package/icons/AlignVerticalJustifyStart.jsx +11 -0
- package/icons/AlignVerticalSpaceAround.jsx +11 -0
- package/icons/AlignVerticalSpaceBetween.jsx +12 -0
- package/icons/Ambulance.jsx +16 -0
- package/icons/Ampersand.jsx +10 -0
- package/icons/Ampersands.jsx +10 -0
- package/icons/Amphora.jsx +14 -0
- package/icons/Anchor.jsx +12 -0
- package/icons/Angry.jsx +14 -0
- package/icons/Annoyed.jsx +12 -0
- package/icons/Antenna.jsx +14 -0
- package/icons/Anvil.jsx +13 -0
- package/icons/Aperture.jsx +15 -0
- package/icons/AppWindow.jsx +12 -0
- package/icons/AppWindowMac.jsx +12 -0
- package/icons/Apple.jsx +10 -0
- package/icons/Archive.jsx +11 -0
- package/icons/ArchiveRestore.jsx +13 -0
- package/icons/ArchiveX.jsx +12 -0
- package/icons/Armchair.jsx +12 -0
- package/icons/ArrowBigDown.jsx +9 -0
- package/icons/ArrowBigDownDash.jsx +10 -0
- package/icons/ArrowBigLeft.jsx +9 -0
- package/icons/ArrowBigLeftDash.jsx +10 -0
- package/icons/ArrowBigRight.jsx +9 -0
- package/icons/ArrowBigRightDash.jsx +10 -0
- package/icons/ArrowBigUp.jsx +9 -0
- package/icons/ArrowBigUpDash.jsx +10 -0
- package/icons/ArrowDown.jsx +10 -0
- package/icons/ArrowDown01.jsx +13 -0
- package/icons/ArrowDown10.jsx +13 -0
- package/icons/ArrowDownAZ.jsx +13 -0
- package/icons/ArrowDownFromLine.jsx +11 -0
- package/icons/ArrowDownLeft.jsx +10 -0
- package/icons/ArrowDownNarrowWide.jsx +13 -0
- package/icons/ArrowDownRight.jsx +10 -0
- package/icons/ArrowDownToDot.jsx +11 -0
- package/icons/ArrowDownToLine.jsx +11 -0
- package/icons/ArrowDownUp.jsx +12 -0
- package/icons/ArrowDownWideNarrow.jsx +13 -0
- package/icons/ArrowDownZA.jsx +13 -0
- package/icons/ArrowLeft.jsx +10 -0
- package/icons/ArrowLeftFromLine.jsx +11 -0
- package/icons/ArrowLeftRight.jsx +12 -0
- package/icons/ArrowLeftToLine.jsx +11 -0
- package/icons/ArrowRight.jsx +10 -0
- package/icons/ArrowRightFromLine.jsx +11 -0
- package/icons/ArrowRightLeft.jsx +12 -0
- package/icons/ArrowRightToLine.jsx +11 -0
- package/icons/ArrowUp.jsx +10 -0
- package/icons/ArrowUp01.jsx +13 -0
- package/icons/ArrowUp10.jsx +13 -0
- package/icons/ArrowUpAZ.jsx +13 -0
- package/icons/ArrowUpDown.jsx +12 -0
- package/icons/ArrowUpFromDot.jsx +11 -0
- package/icons/ArrowUpFromLine.jsx +11 -0
- package/icons/ArrowUpLeft.jsx +10 -0
- package/icons/ArrowUpNarrowWide.jsx +13 -0
- package/icons/ArrowUpRight.jsx +10 -0
- package/icons/ArrowUpToLine.jsx +11 -0
- package/icons/ArrowUpWideNarrow.jsx +13 -0
- package/icons/ArrowUpZA.jsx +13 -0
- package/icons/ArrowsUpFromLine.jsx +13 -0
- package/icons/Asterisk.jsx +11 -0
- package/icons/Astroid.jsx +9 -0
- package/icons/AtSign.jsx +10 -0
- package/icons/Atom.jsx +11 -0
- package/icons/AudioLines.jsx +14 -0
- package/icons/AudioWaveform.jsx +9 -0
- package/icons/Award.jsx +10 -0
- package/icons/Axe.jsx +10 -0
- package/icons/Axis3d.jsx +12 -0
- package/icons/Baby.jsx +12 -0
- package/icons/Backpack.jsx +13 -0
- package/icons/Badge.jsx +9 -0
- package/icons/BadgeAlert.jsx +11 -0
- package/icons/BadgeCent.jsx +11 -0
- package/icons/BadgeCheck.jsx +10 -0
- package/icons/BadgeDollarSign.jsx +11 -0
- package/icons/BadgeEuro.jsx +11 -0
- package/icons/BadgeIndianRupee.jsx +12 -0
- package/icons/BadgeInfo.jsx +11 -0
- package/icons/BadgeJapaneseYen.jsx +13 -0
- package/icons/BadgeMinus.jsx +10 -0
- package/icons/BadgePercent.jsx +12 -0
- package/icons/BadgePlus.jsx +11 -0
- package/icons/BadgePoundSterling.jsx +12 -0
- package/icons/BadgeQuestionMark.jsx +11 -0
- package/icons/BadgeRussianRuble.jsx +11 -0
- package/icons/BadgeSwissFranc.jsx +12 -0
- package/icons/BadgeTurkishLira.jsx +11 -0
- package/icons/BadgeX.jsx +11 -0
- package/icons/BaggageClaim.jsx +13 -0
- package/icons/Balloon.jsx +11 -0
- package/icons/Ban.jsx +10 -0
- package/icons/Banana.jsx +10 -0
- package/icons/Bandage.jsx +15 -0
- package/icons/Banknote.jsx +11 -0
- package/icons/BanknoteArrowDown.jsx +14 -0
- package/icons/BanknoteArrowUp.jsx +14 -0
- package/icons/BanknoteX.jsx +14 -0
- package/icons/Barcode.jsx +13 -0
- package/icons/Barrel.jsx +13 -0
- package/icons/Baseline.jsx +11 -0
- package/icons/Bath.jsx +13 -0
- package/icons/Battery.jsx +10 -0
- package/icons/BatteryCharging.jsx +12 -0
- package/icons/BatteryFull.jsx +13 -0
- package/icons/BatteryLow.jsx +11 -0
- package/icons/BatteryMedium.jsx +12 -0
- package/icons/BatteryPlus.jsx +13 -0
- package/icons/BatteryWarning.jsx +13 -0
- package/icons/Beaker.jsx +11 -0
- package/icons/Bean.jsx +10 -0
- package/icons/BeanOff.jsx +12 -0
- package/icons/Bed.jsx +12 -0
- package/icons/BedDouble.jsx +12 -0
- package/icons/BedSingle.jsx +11 -0
- package/icons/Beef.jsx +11 -0
- package/icons/BeefOff.jsx +14 -0
- package/icons/Beer.jsx +13 -0
- package/icons/BeerOff.jsx +16 -0
- package/icons/Bell.jsx +10 -0
- package/icons/BellCheck.jsx +12 -0
- package/icons/BellDot.jsx +11 -0
- package/icons/BellElectric.jsx +14 -0
- package/icons/BellMinus.jsx +11 -0
- package/icons/BellOff.jsx +12 -0
- package/icons/BellPlus.jsx +12 -0
- package/icons/BellRing.jsx +12 -0
- package/icons/BetweenHorizontalEnd.jsx +11 -0
- package/icons/BetweenHorizontalStart.jsx +11 -0
- package/icons/BetweenVerticalEnd.jsx +11 -0
- package/icons/BetweenVerticalStart.jsx +11 -0
- package/icons/BicepsFlexed.jsx +11 -0
- package/icons/Bike.jsx +12 -0
- package/icons/Binary.jsx +14 -0
- package/icons/Binoculars.jsx +14 -0
- package/icons/Biohazard.jsx +18 -0
- package/icons/Bird.jsx +14 -0
- package/icons/Birdhouse.jsx +14 -0
- package/icons/Bitcoin.jsx +9 -0
- package/icons/Blend.jsx +10 -0
- package/icons/Blinds.jsx +15 -0
- package/icons/Blocks.jsx +10 -0
- package/icons/Bluetooth.jsx +9 -0
- package/icons/BluetoothConnected.jsx +11 -0
- package/icons/BluetoothOff.jsx +11 -0
- package/icons/BluetoothSearching.jsx +11 -0
- package/icons/Bold.jsx +9 -0
- package/icons/Bolt.jsx +10 -0
- package/icons/Bomb.jsx +11 -0
- package/icons/Bone.jsx +9 -0
- package/icons/Book.jsx +9 -0
- package/icons/BookA.jsx +11 -0
- package/icons/BookAlert.jsx +11 -0
- package/icons/BookAudio.jsx +12 -0
- package/icons/BookCheck.jsx +10 -0
- package/icons/BookCopy.jsx +11 -0
- package/icons/BookDashed.jsx +19 -0
- package/icons/BookDown.jsx +11 -0
- package/icons/BookHeadphones.jsx +12 -0
- package/icons/BookHeart.jsx +10 -0
- package/icons/BookImage.jsx +11 -0
- package/icons/BookKey.jsx +13 -0
- package/icons/BookLock.jsx +12 -0
- package/icons/BookMarked.jsx +10 -0
- package/icons/BookMinus.jsx +10 -0
- package/icons/BookOpen.jsx +10 -0
- package/icons/BookOpenCheck.jsx +11 -0
- package/icons/BookOpenText.jsx +14 -0
- package/icons/BookPlus.jsx +11 -0
- package/icons/BookSearch.jsx +12 -0
- package/icons/BookText.jsx +11 -0
- package/icons/BookType.jsx +12 -0
- package/icons/BookUp.jsx +11 -0
- package/icons/BookUp2.jsx +13 -0
- package/icons/BookUser.jsx +11 -0
- package/icons/BookX.jsx +11 -0
- package/icons/Bookmark.jsx +9 -0
- package/icons/BookmarkCheck.jsx +10 -0
- package/icons/BookmarkMinus.jsx +10 -0
- package/icons/BookmarkOff.jsx +11 -0
- package/icons/BookmarkPlus.jsx +11 -0
- package/icons/BookmarkX.jsx +11 -0
- package/icons/BoomBox.jsx +15 -0
- package/icons/Bot.jsx +14 -0
- package/icons/BotMessageSquare.jsx +14 -0
- package/icons/BotOff.jsx +15 -0
- package/icons/BottleWine.jsx +10 -0
- package/icons/BowArrow.jsx +13 -0
- package/icons/Box.jsx +11 -0
- package/icons/Boxes.jsx +20 -0
- package/icons/Braces.jsx +10 -0
- package/icons/Brackets.jsx +10 -0
- package/icons/Brain.jsx +16 -0
- package/icons/BrainCircuit.jsx +21 -0
- package/icons/BrainCog.jsx +23 -0
- package/icons/BrickWall.jsx +16 -0
- package/icons/BrickWallFire.jsx +15 -0
- package/icons/BrickWallShield.jsx +16 -0
- package/icons/Briefcase.jsx +10 -0
- package/icons/BriefcaseBusiness.jsx +12 -0
- package/icons/BriefcaseConveyorBelt.jsx +15 -0
- package/icons/BriefcaseMedical.jsx +14 -0
- package/icons/BringToFront.jsx +11 -0
- package/icons/Brush.jsx +11 -0
- package/icons/BrushCleaning.jsx +12 -0
- package/icons/Bubbles.jsx +12 -0
- package/icons/Bug.jsx +19 -0
- package/icons/BugOff.jsx +20 -0
- package/icons/BugPlay.jsx +17 -0
- package/icons/Building.jsx +19 -0
- package/icons/Building2.jsx +13 -0
- package/icons/Bus.jsx +15 -0
- package/icons/BusFront.jsx +17 -0
- package/icons/Cable.jsx +15 -0
- package/icons/CableCar.jsx +16 -0
- package/icons/Cake.jsx +17 -0
- package/icons/CakeSlice.jsx +12 -0
- package/icons/Calculator.jsx +18 -0
- package/icons/Calendar.jsx +12 -0
- package/icons/Calendar1.jsx +13 -0
- package/icons/CalendarArrowDown.jsx +14 -0
- package/icons/CalendarArrowUp.jsx +14 -0
- package/icons/CalendarCheck.jsx +13 -0
- package/icons/CalendarCheck2.jsx +13 -0
- package/icons/CalendarClock.jsx +14 -0
- package/icons/CalendarCog.jsx +21 -0
- package/icons/CalendarDays.jsx +18 -0
- package/icons/CalendarFold.jsx +13 -0
- package/icons/CalendarHeart.jsx +13 -0
- package/icons/CalendarMinus.jsx +13 -0
- package/icons/CalendarMinus2.jsx +13 -0
- package/icons/CalendarOff.jsx +14 -0
- package/icons/CalendarPlus.jsx +14 -0
- package/icons/CalendarPlus2.jsx +14 -0
- package/icons/CalendarRange.jsx +16 -0
- package/icons/CalendarSearch.jsx +14 -0
- package/icons/CalendarSync.jsx +16 -0
- package/icons/CalendarX.jsx +14 -0
- package/icons/CalendarX2.jsx +14 -0
- package/icons/Calendars.jsx +14 -0
- package/icons/Camera.jsx +10 -0
- package/icons/CameraOff.jsx +12 -0
- package/icons/Candy.jsx +13 -0
- package/icons/CandyCane.jsx +13 -0
- package/icons/CandyOff.jsx +15 -0
- package/icons/Cannabis.jsx +10 -0
- package/icons/CannabisOff.jsx +14 -0
- package/icons/Captions.jsx +10 -0
- package/icons/CaptionsOff.jsx +14 -0
- package/icons/Car.jsx +12 -0
- package/icons/CarFront.jsx +14 -0
- package/icons/CarTaxiFront.jsx +15 -0
- package/icons/Caravan.jsx +12 -0
- package/icons/CardSim.jsx +12 -0
- package/icons/Carrot.jsx +11 -0
- package/icons/CaseLower.jsx +12 -0
- package/icons/CaseSensitive.jsx +12 -0
- package/icons/CaseUpper.jsx +11 -0
- package/icons/CassetteTape.jsx +13 -0
- package/icons/Cast.jsx +12 -0
- package/icons/Castle.jsx +16 -0
- package/icons/Cat.jsx +12 -0
- package/icons/Cctv.jsx +13 -0
- package/icons/CctvOff.jsx +14 -0
- package/icons/ChartArea.jsx +10 -0
- package/icons/ChartBar.jsx +12 -0
- package/icons/ChartBarBig.jsx +11 -0
- package/icons/ChartBarDecreasing.jsx +12 -0
- package/icons/ChartBarIncreasing.jsx +12 -0
- package/icons/ChartBarStacked.jsx +13 -0
- package/icons/ChartCandlestick.jsx +15 -0
- package/icons/ChartColumn.jsx +12 -0
- package/icons/ChartColumnBig.jsx +11 -0
- package/icons/ChartColumnDecreasing.jsx +12 -0
- package/icons/ChartColumnIncreasing.jsx +12 -0
- package/icons/ChartColumnStacked.jsx +13 -0
- package/icons/ChartGantt.jsx +12 -0
- package/icons/ChartLine.jsx +10 -0
- package/icons/ChartNetwork.jsx +15 -0
- package/icons/ChartNoAxesColumn.jsx +11 -0
- package/icons/ChartNoAxesColumnDecreasing.jsx +11 -0
- package/icons/ChartNoAxesColumnIncreasing.jsx +11 -0
- package/icons/ChartNoAxesCombined.jsx +14 -0
- package/icons/ChartNoAxesGantt.jsx +11 -0
- package/icons/ChartPie.jsx +10 -0
- package/icons/ChartScatter.jsx +14 -0
- package/icons/ChartSpline.jsx +10 -0
- package/icons/Check.jsx +9 -0
- package/icons/CheckCheck.jsx +10 -0
- package/icons/CheckLine.jsx +11 -0
- package/icons/ChefHat.jsx +10 -0
- package/icons/Cherry.jsx +12 -0
- package/icons/ChessBishop.jsx +12 -0
- package/icons/ChessKing.jsx +12 -0
- package/icons/ChessKnight.jsx +13 -0
- package/icons/ChessPawn.jsx +13 -0
- package/icons/ChessQueen.jsx +16 -0
- package/icons/ChessRook.jsx +15 -0
- package/icons/ChevronDown.jsx +9 -0
- package/icons/ChevronFirst.jsx +10 -0
- package/icons/ChevronLast.jsx +10 -0
- package/icons/ChevronLeft.jsx +9 -0
- package/icons/ChevronRight.jsx +9 -0
- package/icons/ChevronUp.jsx +9 -0
- package/icons/ChevronsDown.jsx +10 -0
- package/icons/ChevronsDownUp.jsx +10 -0
- package/icons/ChevronsLeft.jsx +10 -0
- package/icons/ChevronsLeftRight.jsx +10 -0
- package/icons/ChevronsLeftRightEllipsis.jsx +13 -0
- package/icons/ChevronsRight.jsx +10 -0
- package/icons/ChevronsRightLeft.jsx +10 -0
- package/icons/ChevronsUp.jsx +10 -0
- package/icons/ChevronsUpDown.jsx +10 -0
- package/icons/Church.jsx +13 -0
- package/icons/Cigarette.jsx +13 -0
- package/icons/CigaretteOff.jsx +14 -0
- package/icons/Circle.jsx +9 -0
- package/icons/CircleAlert.jsx +11 -0
- package/icons/CircleArrowDown.jsx +11 -0
- package/icons/CircleArrowLeft.jsx +11 -0
- package/icons/CircleArrowOutDownLeft.jsx +11 -0
- package/icons/CircleArrowOutDownRight.jsx +11 -0
- package/icons/CircleArrowOutUpLeft.jsx +11 -0
- package/icons/CircleArrowOutUpRight.jsx +11 -0
- package/icons/CircleArrowRight.jsx +11 -0
- package/icons/CircleArrowUp.jsx +11 -0
- package/icons/CircleCheck.jsx +10 -0
- package/icons/CircleCheckBig.jsx +10 -0
- package/icons/CircleChevronDown.jsx +10 -0
- package/icons/CircleChevronLeft.jsx +10 -0
- package/icons/CircleChevronRight.jsx +10 -0
- package/icons/CircleChevronUp.jsx +10 -0
- package/icons/CircleDashed.jsx +16 -0
- package/icons/CircleDivide.jsx +12 -0
- package/icons/CircleDollarSign.jsx +11 -0
- package/icons/CircleDot.jsx +10 -0
- package/icons/CircleDotDashed.jsx +17 -0
- package/icons/CircleEllipsis.jsx +12 -0
- package/icons/CircleEqual.jsx +11 -0
- package/icons/CircleFadingArrowUp.jsx +15 -0
- package/icons/CircleFadingPlus.jsx +15 -0
- package/icons/CircleGauge.jsx +11 -0
- package/icons/CircleMinus.jsx +10 -0
- package/icons/CircleOff.jsx +11 -0
- package/icons/CircleParking.jsx +10 -0
- package/icons/CircleParkingOff.jsx +14 -0
- package/icons/CirclePause.jsx +11 -0
- package/icons/CirclePercent.jsx +12 -0
- package/icons/CirclePile.jsx +14 -0
- package/icons/CirclePlay.jsx +10 -0
- package/icons/CirclePlus.jsx +11 -0
- package/icons/CirclePoundSterling.jsx +12 -0
- package/icons/CirclePower.jsx +11 -0
- package/icons/CircleQuestionMark.jsx +11 -0
- package/icons/CircleSlash.jsx +10 -0
- package/icons/CircleSlash2.jsx +10 -0
- package/icons/CircleSmall.jsx +9 -0
- package/icons/CircleStar.jsx +10 -0
- package/icons/CircleStop.jsx +10 -0
- package/icons/CircleUser.jsx +11 -0
- package/icons/CircleUserRound.jsx +11 -0
- package/icons/CircleX.jsx +11 -0
- package/icons/CircuitBoard.jsx +13 -0
- package/icons/Citrus.jsx +12 -0
- package/icons/Clapperboard.jsx +12 -0
- package/icons/Clipboard.jsx +10 -0
- package/icons/ClipboardCheck.jsx +11 -0
- package/icons/ClipboardClock.jsx +13 -0
- package/icons/ClipboardCopy.jsx +13 -0
- package/icons/ClipboardList.jsx +14 -0
- package/icons/ClipboardMinus.jsx +11 -0
- package/icons/ClipboardPaste.jsx +13 -0
- package/icons/ClipboardPen.jsx +12 -0
- package/icons/ClipboardPenLine.jsx +13 -0
- package/icons/ClipboardPlus.jsx +12 -0
- package/icons/ClipboardType.jsx +13 -0
- package/icons/ClipboardX.jsx +12 -0
- package/icons/Clock.jsx +10 -0
- package/icons/Clock1.jsx +10 -0
- package/icons/Clock10.jsx +10 -0
- package/icons/Clock11.jsx +10 -0
- package/icons/Clock12.jsx +10 -0
- package/icons/Clock2.jsx +10 -0
- package/icons/Clock3.jsx +10 -0
- package/icons/Clock4.jsx +10 -0
- package/icons/Clock5.jsx +10 -0
- package/icons/Clock6.jsx +10 -0
- package/icons/Clock7.jsx +10 -0
- package/icons/Clock8.jsx +10 -0
- package/icons/Clock9.jsx +10 -0
- package/icons/ClockAlert.jsx +12 -0
- package/icons/ClockArrowDown.jsx +12 -0
- package/icons/ClockArrowUp.jsx +12 -0
- package/icons/ClockCheck.jsx +11 -0
- package/icons/ClockFading.jsx +14 -0
- package/icons/ClockPlus.jsx +12 -0
- package/icons/ClosedCaption.jsx +11 -0
- package/icons/Cloud.jsx +9 -0
- package/icons/CloudAlert.jsx +11 -0
- package/icons/CloudBackup.jsx +11 -0
- package/icons/CloudCheck.jsx +10 -0
- package/icons/CloudCog.jsx +17 -0
- package/icons/CloudDownload.jsx +11 -0
- package/icons/CloudDrizzle.jsx +15 -0
- package/icons/CloudFog.jsx +11 -0
- package/icons/CloudHail.jsx +15 -0
- package/icons/CloudLightning.jsx +10 -0
- package/icons/CloudMoon.jsx +10 -0
- package/icons/CloudMoonRain.jsx +12 -0
- package/icons/CloudOff.jsx +11 -0
- package/icons/CloudRain.jsx +12 -0
- package/icons/CloudRainWind.jsx +12 -0
- package/icons/CloudSnow.jsx +15 -0
- package/icons/CloudSun.jsx +14 -0
- package/icons/CloudSunRain.jsx +16 -0
- package/icons/CloudSync.jsx +13 -0
- package/icons/CloudUpload.jsx +11 -0
- package/icons/Cloudy.jsx +10 -0
- package/icons/Clover.jsx +11 -0
- package/icons/Club.jsx +10 -0
- package/icons/Code.jsx +10 -0
- package/icons/CodeXml.jsx +11 -0
- package/icons/Coffee.jsx +12 -0
- package/icons/Cog.jsx +22 -0
- package/icons/Coins.jsx +12 -0
- package/icons/Columns2.jsx +10 -0
- package/icons/Columns3.jsx +11 -0
- package/icons/Columns3Cog.jsx +20 -0
- package/icons/Columns4.jsx +12 -0
- package/icons/Combine.jsx +14 -0
- package/icons/Command.jsx +9 -0
- package/icons/Compass.jsx +10 -0
- package/icons/Component.jsx +12 -0
- package/icons/Computer.jsx +12 -0
- package/icons/ConciergeBell.jsx +12 -0
- package/icons/Cone.jsx +10 -0
- package/icons/Construction.jsx +16 -0
- package/icons/Contact.jsx +13 -0
- package/icons/ContactRound.jsx +13 -0
- package/icons/Container.jsx +13 -0
- package/icons/Contrast.jsx +10 -0
- package/icons/Cookie.jsx +14 -0
- package/icons/CookingPot.jsx +12 -0
- package/icons/Copy.jsx +10 -0
- package/icons/CopyCheck.jsx +11 -0
- package/icons/CopyMinus.jsx +11 -0
- package/icons/CopyPlus.jsx +12 -0
- package/icons/CopySlash.jsx +11 -0
- package/icons/CopyX.jsx +12 -0
- package/icons/Copyleft.jsx +10 -0
- package/icons/Copyright.jsx +10 -0
- package/icons/CornerDownLeft.jsx +10 -0
- package/icons/CornerDownRight.jsx +10 -0
- package/icons/CornerLeftDown.jsx +10 -0
- package/icons/CornerLeftUp.jsx +10 -0
- package/icons/CornerRightDown.jsx +10 -0
- package/icons/CornerRightUp.jsx +10 -0
- package/icons/CornerUpLeft.jsx +10 -0
- package/icons/CornerUpRight.jsx +10 -0
- package/icons/Cpu.jsx +22 -0
- package/icons/CreativeCommons.jsx +11 -0
- package/icons/CreditCard.jsx +10 -0
- package/icons/Croissant.jsx +13 -0
- package/icons/Crop.jsx +10 -0
- package/icons/Cross.jsx +9 -0
- package/icons/Crosshair.jsx +13 -0
- package/icons/Crown.jsx +10 -0
- package/icons/Cuboid.jsx +11 -0
- package/icons/CupSoda.jsx +12 -0
- package/icons/Currency.jsx +13 -0
- package/icons/Cylinder.jsx +10 -0
- package/icons/Dam.jsx +15 -0
- package/icons/Database.jsx +11 -0
- package/icons/DatabaseBackup.jsx +14 -0
- package/icons/DatabaseSearch.jsx +14 -0
- package/icons/DatabaseZap.jsx +13 -0
- package/icons/DecimalsArrowLeft.jsx +12 -0
- package/icons/DecimalsArrowRight.jsx +13 -0
- package/icons/Delete.jsx +11 -0
- package/icons/Dessert.jsx +11 -0
- package/icons/Diameter.jsx +13 -0
- package/icons/Diamond.jsx +9 -0
- package/icons/DiamondMinus.jsx +10 -0
- package/icons/DiamondPercent.jsx +12 -0
- package/icons/DiamondPlus.jsx +11 -0
- package/icons/Dice1.jsx +10 -0
- package/icons/Dice2.jsx +11 -0
- package/icons/Dice3.jsx +12 -0
- package/icons/Dice4.jsx +13 -0
- package/icons/Dice5.jsx +14 -0
- package/icons/Dice6.jsx +15 -0
- package/icons/Dices.jsx +14 -0
- package/icons/Diff.jsx +11 -0
- package/icons/Disc.jsx +10 -0
- package/icons/Disc2.jsx +11 -0
- package/icons/Disc3.jsx +12 -0
- package/icons/DiscAlbum.jsx +11 -0
- package/icons/Divide.jsx +11 -0
- package/icons/Dna.jsx +19 -0
- package/icons/DnaOff.jsx +18 -0
- package/icons/Dock.jsx +11 -0
- package/icons/Dog.jsx +13 -0
- package/icons/DollarSign.jsx +10 -0
- package/icons/Donut.jsx +10 -0
- package/icons/DoorClosed.jsx +11 -0
- package/icons/DoorClosedLocked.jsx +13 -0
- package/icons/DoorOpen.jsx +13 -0
- package/icons/Dot.jsx +9 -0
- package/icons/Download.jsx +11 -0
- package/icons/DraftingCompass.jsx +13 -0
- package/icons/Drama.jsx +16 -0
- package/icons/Drill.jsx +14 -0
- package/icons/Drone.jsx +17 -0
- package/icons/Droplet.jsx +9 -0
- package/icons/DropletOff.jsx +11 -0
- package/icons/Droplets.jsx +10 -0
- package/icons/Drum.jsx +15 -0
- package/icons/Drumstick.jsx +10 -0
- package/icons/Dumbbell.jsx +13 -0
- package/icons/Ear.jsx +10 -0
- package/icons/EarOff.jsx +13 -0
- package/icons/Earth.jsx +12 -0
- package/icons/EarthLock.jsx +14 -0
- package/icons/Eclipse.jsx +10 -0
- package/icons/Egg.jsx +9 -0
- package/icons/EggFried.jsx +10 -0
- package/icons/EggOff.jsx +11 -0
- package/icons/Ellipse.jsx +9 -0
- package/icons/Ellipsis.jsx +11 -0
- package/icons/EllipsisVertical.jsx +11 -0
- package/icons/Equal.jsx +10 -0
- package/icons/EqualApproximately.jsx +10 -0
- package/icons/EqualNot.jsx +11 -0
- package/icons/Eraser.jsx +10 -0
- package/icons/EthernetPort.jsx +13 -0
- package/icons/Euro.jsx +11 -0
- package/icons/EvCharger.jsx +13 -0
- package/icons/Expand.jsx +16 -0
- package/icons/ExternalLink.jsx +11 -0
- package/icons/Eye.jsx +10 -0
- package/icons/EyeClosed.jsx +13 -0
- package/icons/EyeOff.jsx +12 -0
- package/icons/Factory.jsx +12 -0
- package/icons/Fan.jsx +10 -0
- package/icons/FastForward.jsx +10 -0
- package/icons/Feather.jsx +11 -0
- package/icons/Fence.jsx +15 -0
- package/icons/FerrisWheel.jsx +17 -0
- package/icons/File.jsx +10 -0
- package/icons/FileArchive.jsx +14 -0
- package/icons/FileAxis3d.jsx +12 -0
- package/icons/FileBadge.jsx +12 -0
- package/icons/FileBox.jsx +13 -0
- package/icons/FileBraces.jsx +12 -0
- package/icons/FileBracesCorner.jsx +12 -0
- package/icons/FileChartColumn.jsx +13 -0
- package/icons/FileChartColumnIncreasing.jsx +13 -0
- package/icons/FileChartLine.jsx +11 -0
- package/icons/FileChartPie.jsx +12 -0
- package/icons/FileCheck.jsx +11 -0
- package/icons/FileCheckCorner.jsx +11 -0
- package/icons/FileClock.jsx +12 -0
- package/icons/FileCode.jsx +12 -0
- package/icons/FileCodeCorner.jsx +12 -0
- package/icons/FileCog.jsx +20 -0
- package/icons/FileDiff.jsx +12 -0
- package/icons/FileDigit.jsx +13 -0
- package/icons/FileDown.jsx +12 -0
- package/icons/FileExclamationPoint.jsx +11 -0
- package/icons/FileHeadphone.jsx +11 -0
- package/icons/FileHeart.jsx +11 -0
- package/icons/FileImage.jsx +12 -0
- package/icons/FileInput.jsx +12 -0
- package/icons/FileKey.jsx +13 -0
- package/icons/FileLock.jsx +12 -0
- package/icons/FileMinus.jsx +11 -0
- package/icons/FileMinusCorner.jsx +11 -0
- package/icons/FileMusic.jsx +12 -0
- package/icons/FileOutput.jsx +12 -0
- package/icons/FilePen.jsx +11 -0
- package/icons/FilePenLine.jsx +12 -0
- package/icons/FilePlay.jsx +11 -0
- package/icons/FilePlus.jsx +12 -0
- package/icons/FilePlusCorner.jsx +12 -0
- package/icons/FileQuestionMark.jsx +11 -0
- package/icons/FileScan.jsx +14 -0
- package/icons/FileSearch.jsx +12 -0
- package/icons/FileSearchCorner.jsx +12 -0
- package/icons/FileSignal.jsx +13 -0
- package/icons/FileSliders.jsx +14 -0
- package/icons/FileSpreadsheet.jsx +14 -0
- package/icons/FileStack.jsx +11 -0
- package/icons/FileSymlink.jsx +11 -0
- package/icons/FileTerminal.jsx +12 -0
- package/icons/FileText.jsx +13 -0
- package/icons/FileType.jsx +13 -0
- package/icons/FileTypeCorner.jsx +13 -0
- package/icons/FileUp.jsx +12 -0
- package/icons/FileUser.jsx +12 -0
- package/icons/FileVideoCamera.jsx +12 -0
- package/icons/FileVolume.jsx +12 -0
- package/icons/FileX.jsx +12 -0
- package/icons/FileXCorner.jsx +12 -0
- package/icons/Files.jsx +11 -0
- package/icons/Film.jsx +16 -0
- package/icons/FingerprintPattern.jsx +17 -0
- package/icons/FireExtinguisher.jsx +14 -0
- package/icons/Fish.jsx +14 -0
- package/icons/FishOff.jsx +11 -0
- package/icons/FishSymbol.jsx +9 -0
- package/icons/FishingHook.jsx +11 -0
- package/icons/FishingRod.jsx +11 -0
- package/icons/Flag.jsx +9 -0
- package/icons/FlagOff.jsx +12 -0
- package/icons/FlagTriangleLeft.jsx +9 -0
- package/icons/FlagTriangleRight.jsx +9 -0
- package/icons/Flame.jsx +9 -0
- package/icons/FlameKindling.jsx +11 -0
- package/icons/Flashlight.jsx +11 -0
- package/icons/FlashlightOff.jsx +13 -0
- package/icons/FlaskConical.jsx +11 -0
- package/icons/FlaskConicalOff.jsx +14 -0
- package/icons/FlaskRound.jsx +11 -0
- package/icons/FlipHorizontal2.jsx +14 -0
- package/icons/FlipVertical2.jsx +14 -0
- package/icons/Flower.jsx +18 -0
- package/icons/Flower2.jsx +13 -0
- package/icons/Focus.jsx +13 -0
- package/icons/FoldHorizontal.jsx +16 -0
- package/icons/FoldVertical.jsx +16 -0
- package/icons/Folder.jsx +9 -0
- package/icons/FolderArchive.jsx +12 -0
- package/icons/FolderBookmark.jsx +10 -0
- package/icons/FolderCheck.jsx +10 -0
- package/icons/FolderClock.jsx +11 -0
- package/icons/FolderClosed.jsx +10 -0
- package/icons/FolderCode.jsx +11 -0
- package/icons/FolderCog.jsx +18 -0
- package/icons/FolderDot.jsx +10 -0
- package/icons/FolderDown.jsx +11 -0
- package/icons/FolderGit.jsx +12 -0
- package/icons/FolderGit2.jsx +12 -0
- package/icons/FolderHeart.jsx +10 -0
- package/icons/FolderInput.jsx +11 -0
- package/icons/FolderKanban.jsx +12 -0
- package/icons/FolderKey.jsx +12 -0
- package/icons/FolderLock.jsx +11 -0
- package/icons/FolderMinus.jsx +10 -0
- package/icons/FolderOpen.jsx +9 -0
- package/icons/FolderOpenDot.jsx +10 -0
- package/icons/FolderOutput.jsx +11 -0
- package/icons/FolderPen.jsx +10 -0
- package/icons/FolderPlus.jsx +11 -0
- package/icons/FolderRoot.jsx +11 -0
- package/icons/FolderSearch.jsx +11 -0
- package/icons/FolderSearch2.jsx +11 -0
- package/icons/FolderSymlink.jsx +10 -0
- package/icons/FolderSync.jsx +13 -0
- package/icons/FolderTree.jsx +12 -0
- package/icons/FolderUp.jsx +11 -0
- package/icons/FolderX.jsx +11 -0
- package/icons/Folders.jsx +10 -0
- package/icons/Footprints.jsx +12 -0
- package/icons/Forklift.jsx +15 -0
- package/icons/Form.jsx +12 -0
- package/icons/Forward.jsx +10 -0
- package/icons/Frame.jsx +12 -0
- package/icons/Frown.jsx +12 -0
- package/icons/Fuel.jsx +12 -0
- package/icons/Fullscreen.jsx +13 -0
- package/icons/Funnel.jsx +9 -0
- package/icons/FunnelPlus.jsx +11 -0
- package/icons/FunnelX.jsx +11 -0
- package/icons/GalleryHorizontal.jsx +11 -0
- package/icons/GalleryHorizontalEnd.jsx +11 -0
- package/icons/GalleryThumbnails.jsx +13 -0
- package/icons/GalleryVertical.jsx +11 -0
- package/icons/GalleryVerticalEnd.jsx +11 -0
- package/icons/Gamepad.jsx +13 -0
- package/icons/Gamepad2.jsx +13 -0
- package/icons/GamepadDirectional.jsx +16 -0
- package/icons/Gauge.jsx +10 -0
- package/icons/Gavel.jsx +13 -0
- package/icons/Gem.jsx +11 -0
- package/icons/GeorgianLari.jsx +12 -0
- package/icons/Ghost.jsx +11 -0
- package/icons/Gift.jsx +12 -0
- package/icons/GitBranch.jsx +11 -0
- package/icons/GitBranchMinus.jsx +12 -0
- package/icons/GitBranchPlus.jsx +14 -0
- package/icons/GitCommitHorizontal.jsx +11 -0
- package/icons/GitCommitVertical.jsx +11 -0
- package/icons/GitCompare.jsx +12 -0
- package/icons/GitCompareArrows.jsx +14 -0
- package/icons/GitFork.jsx +13 -0
- package/icons/GitGraph.jsx +14 -0
- package/icons/GitMerge.jsx +11 -0
- package/icons/GitMergeConflict.jsx +13 -0
- package/icons/GitPullRequest.jsx +12 -0
- package/icons/GitPullRequestArrow.jsx +13 -0
- package/icons/GitPullRequestClosed.jsx +14 -0
- package/icons/GitPullRequestCreate.jsx +13 -0
- package/icons/GitPullRequestCreateArrow.jsx +14 -0
- package/icons/GitPullRequestDraft.jsx +13 -0
- package/icons/GlassWater.jsx +10 -0
- package/icons/Glasses.jsx +13 -0
- package/icons/Globe.jsx +11 -0
- package/icons/GlobeLock.jsx +12 -0
- package/icons/GlobeOff.jsx +15 -0
- package/icons/GlobeX.jsx +11 -0
- package/icons/Goal.jsx +11 -0
- package/icons/Gpu.jsx +13 -0
- package/icons/GraduationCap.jsx +11 -0
- package/icons/Grape.jsx +17 -0
- package/icons/Grid2x2.jsx +11 -0
- package/icons/Grid2x2Check.jsx +10 -0
- package/icons/Grid2x2Plus.jsx +11 -0
- package/icons/Grid2x2X.jsx +11 -0
- package/icons/Grid3x2.jsx +12 -0
- package/icons/Grid3x3.jsx +13 -0
- package/icons/Grip.jsx +17 -0
- package/icons/GripHorizontal.jsx +14 -0
- package/icons/GripVertical.jsx +14 -0
- package/icons/Group.jsx +14 -0
- package/icons/Guitar.jsx +12 -0
- package/icons/Ham.jsx +12 -0
- package/icons/Hamburger.jsx +12 -0
- package/icons/Hammer.jsx +11 -0
- package/icons/Hand.jsx +12 -0
- package/icons/HandCoins.jsx +13 -0
- package/icons/HandFist.jsx +12 -0
- package/icons/HandGrab.jsx +13 -0
- package/icons/HandHeart.jsx +12 -0
- package/icons/HandHelping.jsx +11 -0
- package/icons/HandMetal.jsx +12 -0
- package/icons/HandPlatter.jsx +14 -0
- package/icons/Handbag.jsx +10 -0
- package/icons/Handshake.jsx +13 -0
- package/icons/HardDrive.jsx +12 -0
- package/icons/HardDriveDownload.jsx +13 -0
- package/icons/HardDriveUpload.jsx +13 -0
- package/icons/HardHat.jsx +12 -0
- package/icons/Hash.jsx +12 -0
- package/icons/HatGlasses.jsx +13 -0
- package/icons/Haze.jsx +16 -0
- package/icons/Hd.jsx +13 -0
- package/icons/HdmiPort.jsx +10 -0
- package/icons/Heading.jsx +11 -0
- package/icons/Heading1.jsx +12 -0
- package/icons/Heading2.jsx +12 -0
- package/icons/Heading3.jsx +13 -0
- package/icons/Heading4.jsx +13 -0
- package/icons/Heading5.jsx +13 -0
- package/icons/Heading6.jsx +13 -0
- package/icons/HeadphoneOff.jsx +13 -0
- package/icons/Headphones.jsx +9 -0
- package/icons/Headset.jsx +10 -0
- package/icons/Heart.jsx +9 -0
- package/icons/HeartCrack.jsx +10 -0
- package/icons/HeartHandshake.jsx +9 -0
- package/icons/HeartMinus.jsx +10 -0
- package/icons/HeartOff.jsx +11 -0
- package/icons/HeartPlus.jsx +11 -0
- package/icons/HeartPulse.jsx +10 -0
- package/icons/HeartX.jsx +11 -0
- package/icons/Heater.jsx +18 -0
- package/icons/Helicopter.jsx +16 -0
- package/icons/Hexagon.jsx +9 -0
- package/icons/Highlighter.jsx +10 -0
- package/icons/History.jsx +11 -0
- package/icons/Hop.jsx +16 -0
- package/icons/HopOff.jsx +17 -0
- package/icons/Hospital.jsx +13 -0
- package/icons/Hotel.jsx +18 -0
- package/icons/Hourglass.jsx +12 -0
- package/icons/House.jsx +10 -0
- package/icons/HouseHeart.jsx +10 -0
- package/icons/HousePlug.jsx +12 -0
- package/icons/HousePlus.jsx +12 -0
- package/icons/HouseWifi.jsx +12 -0
- package/icons/IceCreamBowl.jsx +11 -0
- package/icons/IceCreamCone.jsx +11 -0
- package/icons/IdCard.jsx +13 -0
- package/icons/IdCardLanyard.jsx +13 -0
- package/icons/Image.jsx +11 -0
- package/icons/ImageDown.jsx +12 -0
- package/icons/ImageMinus.jsx +12 -0
- package/icons/ImageOff.jsx +14 -0
- package/icons/ImagePlay.jsx +12 -0
- package/icons/ImagePlus.jsx +13 -0
- package/icons/ImageUp.jsx +12 -0
- package/icons/ImageUpscale.jsx +16 -0
- package/icons/Images.jsx +12 -0
- package/icons/Import.jsx +11 -0
- package/icons/Inbox.jsx +10 -0
- package/icons/IndianRupee.jsx +13 -0
- package/icons/Infinity.jsx +9 -0
- package/icons/Info.jsx +11 -0
- package/icons/InspectionPanel.jsx +13 -0
- package/icons/Italic.jsx +11 -0
- package/icons/IterationCcw.jsx +10 -0
- package/icons/IterationCw.jsx +10 -0
- package/icons/JapaneseYen.jsx +11 -0
- package/icons/Joystick.jsx +12 -0
- package/icons/Kanban.jsx +11 -0
- package/icons/Kayak.jsx +12 -0
- package/icons/Key.jsx +11 -0
- package/icons/KeyRound.jsx +10 -0
- package/icons/KeySquare.jsx +11 -0
- package/icons/Keyboard.jsx +17 -0
- package/icons/KeyboardMusic.jsx +17 -0
- package/icons/KeyboardOff.jsx +18 -0
- package/icons/LICENSE +43 -0
- package/icons/Lamp.jsx +11 -0
- package/icons/LampCeiling.jsx +11 -0
- package/icons/LampDesk.jsx +12 -0
- package/icons/LampFloor.jsx +11 -0
- package/icons/LampWallDown.jsx +11 -0
- package/icons/LampWallUp.jsx +11 -0
- package/icons/LandPlot.jsx +12 -0
- package/icons/Landmark.jsx +14 -0
- package/icons/Languages.jsx +14 -0
- package/icons/Laptop.jsx +10 -0
- package/icons/LaptopMinimal.jsx +10 -0
- package/icons/LaptopMinimalCheck.jsx +11 -0
- package/icons/Lasso.jsx +11 -0
- package/icons/LassoSelect.jsx +13 -0
- package/icons/Laugh.jsx +12 -0
- package/icons/Layers.jsx +11 -0
- package/icons/Layers2.jsx +10 -0
- package/icons/LayersMinus.jsx +13 -0
- package/icons/LayersPlus.jsx +13 -0
- package/icons/LayoutDashboard.jsx +12 -0
- package/icons/LayoutGrid.jsx +12 -0
- package/icons/LayoutList.jsx +14 -0
- package/icons/LayoutPanelLeft.jsx +11 -0
- package/icons/LayoutPanelTop.jsx +11 -0
- package/icons/LayoutTemplate.jsx +11 -0
- package/icons/Leaf.jsx +10 -0
- package/icons/LeafyGreen.jsx +10 -0
- package/icons/Lectern.jsx +11 -0
- package/icons/LensConcave.jsx +9 -0
- package/icons/LensConvex.jsx +10 -0
- package/icons/Library.jsx +12 -0
- package/icons/LibraryBig.jsx +11 -0
- package/icons/LifeBuoy.jsx +14 -0
- package/icons/Ligature.jsx +13 -0
- package/icons/Lightbulb.jsx +11 -0
- package/icons/LightbulbOff.jsx +13 -0
- package/icons/LineDotRightHorizontal.jsx +10 -0
- package/icons/LineSquiggle.jsx +9 -0
- package/icons/LineStyle.jsx +14 -0
- package/icons/Link.jsx +10 -0
- package/icons/Link2.jsx +11 -0
- package/icons/Link2Off.jsx +12 -0
- package/icons/List.jsx +14 -0
- package/icons/ListCheck.jsx +12 -0
- package/icons/ListChecks.jsx +13 -0
- package/icons/ListChevronsDownUp.jsx +13 -0
- package/icons/ListChevronsUpDown.jsx +13 -0
- package/icons/ListCollapse.jsx +13 -0
- package/icons/ListEnd.jsx +13 -0
- package/icons/ListFilter.jsx +11 -0
- package/icons/ListFilterPlus.jsx +13 -0
- package/icons/ListIndentDecrease.jsx +12 -0
- package/icons/ListIndentIncrease.jsx +12 -0
- package/icons/ListMinus.jsx +12 -0
- package/icons/ListMusic.jsx +13 -0
- package/icons/ListOrdered.jsx +14 -0
- package/icons/ListPlus.jsx +13 -0
- package/icons/ListRestart.jsx +13 -0
- package/icons/ListStart.jsx +13 -0
- package/icons/ListTodo.jsx +13 -0
- package/icons/ListTree.jsx +13 -0
- package/icons/ListVideo.jsx +12 -0
- package/icons/ListX.jsx +13 -0
- package/icons/Loader.jsx +16 -0
- package/icons/LoaderCircle.jsx +9 -0
- package/icons/LoaderPinwheel.jsx +12 -0
- package/icons/Locate.jsx +13 -0
- package/icons/LocateFixed.jsx +14 -0
- package/icons/LocateOff.jsx +15 -0
- package/icons/Lock.jsx +10 -0
- package/icons/LockKeyhole.jsx +11 -0
- package/icons/LockKeyholeOpen.jsx +11 -0
- package/icons/LockOpen.jsx +10 -0
- package/icons/LogIn.jsx +11 -0
- package/icons/LogOut.jsx +11 -0
- package/icons/Logs.jsx +17 -0
- package/icons/Lollipop.jsx +11 -0
- package/icons/Luggage.jsx +13 -0
- package/icons/Magnet.jsx +11 -0
- package/icons/Mail.jsx +10 -0
- package/icons/MailCheck.jsx +11 -0
- package/icons/MailMinus.jsx +11 -0
- package/icons/MailOpen.jsx +10 -0
- package/icons/MailPlus.jsx +12 -0
- package/icons/MailQuestionMark.jsx +12 -0
- package/icons/MailSearch.jsx +13 -0
- package/icons/MailWarning.jsx +12 -0
- package/icons/MailX.jsx +12 -0
- package/icons/Mailbox.jsx +12 -0
- package/icons/Mails.jsx +11 -0
- package/icons/Map.jsx +11 -0
- package/icons/MapMinus.jsx +12 -0
- package/icons/MapPin.jsx +10 -0
- package/icons/MapPinCheck.jsx +11 -0
- package/icons/MapPinCheckInside.jsx +10 -0
- package/icons/MapPinHouse.jsx +12 -0
- package/icons/MapPinMinus.jsx +11 -0
- package/icons/MapPinMinusInside.jsx +10 -0
- package/icons/MapPinOff.jsx +13 -0
- package/icons/MapPinPen.jsx +11 -0
- package/icons/MapPinPlus.jsx +12 -0
- package/icons/MapPinPlusInside.jsx +11 -0
- package/icons/MapPinSearch.jsx +12 -0
- package/icons/MapPinX.jsx +12 -0
- package/icons/MapPinXInside.jsx +11 -0
- package/icons/MapPinned.jsx +11 -0
- package/icons/MapPlus.jsx +13 -0
- package/icons/Mars.jsx +11 -0
- package/icons/MarsStroke.jsx +12 -0
- package/icons/Martini.jsx +11 -0
- package/icons/Maximize.jsx +12 -0
- package/icons/Maximize2.jsx +12 -0
- package/icons/Medal.jsx +14 -0
- package/icons/Megaphone.jsx +11 -0
- package/icons/MegaphoneOff.jsx +13 -0
- package/icons/Meh.jsx +12 -0
- package/icons/MemoryStick.jsx +19 -0
- package/icons/Menu.jsx +11 -0
- package/icons/Merge.jsx +11 -0
- package/icons/MessageCircle.jsx +9 -0
- package/icons/MessageCircleCheck.jsx +10 -0
- package/icons/MessageCircleCode.jsx +11 -0
- package/icons/MessageCircleDashed.jsx +16 -0
- package/icons/MessageCircleHeart.jsx +10 -0
- package/icons/MessageCircleMore.jsx +12 -0
- package/icons/MessageCircleOff.jsx +11 -0
- package/icons/MessageCirclePlus.jsx +11 -0
- package/icons/MessageCircleQuestionMark.jsx +11 -0
- package/icons/MessageCircleReply.jsx +11 -0
- package/icons/MessageCircleWarning.jsx +11 -0
- package/icons/MessageCircleX.jsx +11 -0
- package/icons/MessageSquare.jsx +9 -0
- package/icons/MessageSquareCheck.jsx +10 -0
- package/icons/MessageSquareCode.jsx +11 -0
- package/icons/MessageSquareDashed.jsx +18 -0
- package/icons/MessageSquareDiff.jsx +12 -0
- package/icons/MessageSquareDot.jsx +10 -0
- package/icons/MessageSquareHeart.jsx +10 -0
- package/icons/MessageSquareLock.jsx +11 -0
- package/icons/MessageSquareMore.jsx +12 -0
- package/icons/MessageSquareOff.jsx +11 -0
- package/icons/MessageSquarePlus.jsx +11 -0
- package/icons/MessageSquareQuote.jsx +11 -0
- package/icons/MessageSquareReply.jsx +11 -0
- package/icons/MessageSquareShare.jsx +11 -0
- package/icons/MessageSquareText.jsx +12 -0
- package/icons/MessageSquareWarning.jsx +11 -0
- package/icons/MessageSquareX.jsx +11 -0
- package/icons/MessagesSquare.jsx +10 -0
- package/icons/Metronome.jsx +12 -0
- package/icons/Mic.jsx +11 -0
- package/icons/MicOff.jsx +14 -0
- package/icons/MicVocal.jsx +11 -0
- package/icons/Microchip.jsx +18 -0
- package/icons/Microscope.jsx +14 -0
- package/icons/Microwave.jsx +13 -0
- package/icons/Milestone.jsx +11 -0
- package/icons/Milk.jsx +11 -0
- package/icons/MilkOff.jsx +12 -0
- package/icons/Minimize.jsx +12 -0
- package/icons/Minimize2.jsx +12 -0
- package/icons/Minus.jsx +9 -0
- package/icons/MirrorRectangular.jsx +11 -0
- package/icons/MirrorRound.jsx +13 -0
- package/icons/Monitor.jsx +11 -0
- package/icons/MonitorCheck.jsx +12 -0
- package/icons/MonitorCloud.jsx +12 -0
- package/icons/MonitorCog.jsx +20 -0
- package/icons/MonitorDot.jsx +12 -0
- package/icons/MonitorDown.jsx +13 -0
- package/icons/MonitorOff.jsx +13 -0
- package/icons/MonitorPause.jsx +13 -0
- package/icons/MonitorPlay.jsx +12 -0
- package/icons/MonitorSmartphone.jsx +12 -0
- package/icons/MonitorSpeaker.jsx +13 -0
- package/icons/MonitorStop.jsx +12 -0
- package/icons/MonitorUp.jsx +13 -0
- package/icons/MonitorX.jsx +13 -0
- package/icons/Moon.jsx +9 -0
- package/icons/MoonStar.jsx +11 -0
- package/icons/Motorbike.jsx +13 -0
- package/icons/Mountain.jsx +9 -0
- package/icons/MountainSnow.jsx +10 -0
- package/icons/Mouse.jsx +10 -0
- package/icons/MouseLeft.jsx +11 -0
- package/icons/MouseOff.jsx +12 -0
- package/icons/MousePointer.jsx +10 -0
- package/icons/MousePointer2.jsx +9 -0
- package/icons/MousePointer2Off.jsx +11 -0
- package/icons/MousePointerBan.jsx +11 -0
- package/icons/MousePointerClick.jsx +13 -0
- package/icons/MouseRight.jsx +11 -0
- package/icons/Move.jsx +14 -0
- package/icons/Move3d.jsx +12 -0
- package/icons/MoveDiagonal.jsx +11 -0
- package/icons/MoveDiagonal2.jsx +11 -0
- package/icons/MoveDown.jsx +10 -0
- package/icons/MoveDownLeft.jsx +10 -0
- package/icons/MoveDownRight.jsx +10 -0
- package/icons/MoveHorizontal.jsx +11 -0
- package/icons/MoveLeft.jsx +10 -0
- package/icons/MoveRight.jsx +10 -0
- package/icons/MoveUp.jsx +10 -0
- package/icons/MoveUpLeft.jsx +10 -0
- package/icons/MoveUpRight.jsx +10 -0
- package/icons/MoveVertical.jsx +11 -0
- package/icons/Music.jsx +11 -0
- package/icons/Music2.jsx +10 -0
- package/icons/Music3.jsx +10 -0
- package/icons/Music4.jsx +12 -0
- package/icons/Navigation.jsx +9 -0
- package/icons/Navigation2.jsx +9 -0
- package/icons/Navigation2Off.jsx +11 -0
- package/icons/NavigationOff.jsx +11 -0
- package/icons/Network.jsx +13 -0
- package/icons/Newspaper.jsx +12 -0
- package/icons/Nfc.jsx +12 -0
- package/icons/NonBinary.jsx +12 -0
- package/icons/Notebook.jsx +14 -0
- package/icons/NotebookPen.jsx +14 -0
- package/icons/NotebookTabs.jsx +17 -0
- package/icons/NotebookText.jsx +16 -0
- package/icons/NotepadText.jsx +15 -0
- package/icons/NotepadTextDashed.jsx +21 -0
- package/icons/Nut.jsx +11 -0
- package/icons/NutOff.jsx +13 -0
- package/icons/Octagon.jsx +9 -0
- package/icons/OctagonAlert.jsx +11 -0
- package/icons/OctagonMinus.jsx +10 -0
- package/icons/OctagonPause.jsx +11 -0
- package/icons/OctagonX.jsx +11 -0
- package/icons/Omega.jsx +9 -0
- package/icons/Option.jsx +10 -0
- package/icons/Orbit.jsx +13 -0
- package/icons/Origami.jsx +11 -0
- package/icons/Package.jsx +12 -0
- package/icons/Package2.jsx +11 -0
- package/icons/PackageCheck.jsx +13 -0
- package/icons/PackageMinus.jsx +13 -0
- package/icons/PackageOpen.jsx +12 -0
- package/icons/PackagePlus.jsx +14 -0
- package/icons/PackageSearch.jsx +14 -0
- package/icons/PackageX.jsx +14 -0
- package/icons/PaintBucket.jsx +12 -0
- package/icons/PaintRoller.jsx +11 -0
- package/icons/Paintbrush.jsx +11 -0
- package/icons/PaintbrushVertical.jsx +12 -0
- package/icons/Palette.jsx +13 -0
- package/icons/Panda.jsx +14 -0
- package/icons/PanelBottom.jsx +10 -0
- package/icons/PanelBottomClose.jsx +11 -0
- package/icons/PanelBottomDashed.jsx +13 -0
- package/icons/PanelBottomOpen.jsx +11 -0
- package/icons/PanelLeft.jsx +10 -0
- package/icons/PanelLeftClose.jsx +11 -0
- package/icons/PanelLeftDashed.jsx +13 -0
- package/icons/PanelLeftOpen.jsx +11 -0
- package/icons/PanelLeftRightDashed.jsx +17 -0
- package/icons/PanelRight.jsx +10 -0
- package/icons/PanelRightClose.jsx +11 -0
- package/icons/PanelRightDashed.jsx +13 -0
- package/icons/PanelRightOpen.jsx +11 -0
- package/icons/PanelTop.jsx +10 -0
- package/icons/PanelTopBottomDashed.jsx +17 -0
- package/icons/PanelTopClose.jsx +11 -0
- package/icons/PanelTopDashed.jsx +13 -0
- package/icons/PanelTopOpen.jsx +11 -0
- package/icons/PanelsLeftBottom.jsx +11 -0
- package/icons/PanelsRightBottom.jsx +11 -0
- package/icons/PanelsTopLeft.jsx +11 -0
- package/icons/Paperclip.jsx +9 -0
- package/icons/Parentheses.jsx +10 -0
- package/icons/ParkingMeter.jsx +13 -0
- package/icons/PartyPopper.jsx +17 -0
- package/icons/Pause.jsx +10 -0
- package/icons/PawPrint.jsx +12 -0
- package/icons/PcCase.jsx +12 -0
- package/icons/Pen.jsx +9 -0
- package/icons/PenLine.jsx +10 -0
- package/icons/PenOff.jsx +11 -0
- package/icons/PenTool.jsx +12 -0
- package/icons/Pencil.jsx +10 -0
- package/icons/PencilLine.jsx +11 -0
- package/icons/PencilOff.jsx +12 -0
- package/icons/PencilRuler.jsx +14 -0
- package/icons/Pentagon.jsx +9 -0
- package/icons/Percent.jsx +11 -0
- package/icons/PersonStanding.jsx +12 -0
- package/icons/PhilippinePeso.jsx +11 -0
- package/icons/Phone.jsx +9 -0
- package/icons/PhoneCall.jsx +11 -0
- package/icons/PhoneForwarded.jsx +11 -0
- package/icons/PhoneIncoming.jsx +11 -0
- package/icons/PhoneMissed.jsx +11 -0
- package/icons/PhoneOff.jsx +11 -0
- package/icons/PhoneOutgoing.jsx +11 -0
- package/icons/Pi.jsx +11 -0
- package/icons/Piano.jsx +14 -0
- package/icons/Pickaxe.jsx +12 -0
- package/icons/PictureInPicture.jsx +13 -0
- package/icons/PictureInPicture2.jsx +10 -0
- package/icons/PiggyBank.jsx +11 -0
- package/icons/Pilcrow.jsx +11 -0
- package/icons/PilcrowLeft.jsx +13 -0
- package/icons/PilcrowRight.jsx +13 -0
- package/icons/Pill.jsx +10 -0
- package/icons/PillBottle.jsx +11 -0
- package/icons/Pin.jsx +10 -0
- package/icons/PinOff.jsx +12 -0
- package/icons/Pipette.jsx +11 -0
- package/icons/Pizza.jsx +13 -0
- package/icons/Plane.jsx +9 -0
- package/icons/PlaneLanding.jsx +10 -0
- package/icons/PlaneTakeoff.jsx +10 -0
- package/icons/Play.jsx +9 -0
- package/icons/Plug.jsx +12 -0
- package/icons/Plug2.jsx +13 -0
- package/icons/PlugZap.jsx +13 -0
- package/icons/Plus.jsx +10 -0
- package/icons/PocketKnife.jsx +13 -0
- package/icons/Podcast.jsx +12 -0
- package/icons/Pointer.jsx +13 -0
- package/icons/PointerOff.jsx +14 -0
- package/icons/Popcorn.jsx +12 -0
- package/icons/Popsicle.jsx +10 -0
- package/icons/PoundSterling.jsx +12 -0
- package/icons/Power.jsx +10 -0
- package/icons/PowerOff.jsx +12 -0
- package/icons/Presentation.jsx +11 -0
- package/icons/Printer.jsx +11 -0
- package/icons/PrinterCheck.jsx +12 -0
- package/icons/PrinterX.jsx +13 -0
- package/icons/Projector.jsx +14 -0
- package/icons/Proportions.jsx +11 -0
- package/icons/Puzzle.jsx +9 -0
- package/icons/Pyramid.jsx +10 -0
- package/icons/QrCode.jsx +20 -0
- package/icons/Quote.jsx +10 -0
- package/icons/Rabbit.jsx +13 -0
- package/icons/Radar.jsx +16 -0
- package/icons/Radiation.jsx +12 -0
- package/icons/Radical.jsx +9 -0
- package/icons/Radio.jsx +13 -0
- package/icons/RadioOff.jsx +14 -0
- package/icons/RadioReceiver.jsx +12 -0
- package/icons/RadioTower.jsx +15 -0
- package/icons/Radius.jsx +12 -0
- package/icons/Rainbow.jsx +11 -0
- package/icons/Rat.jsx +13 -0
- package/icons/Ratio.jsx +10 -0
- package/icons/Receipt.jsx +11 -0
- package/icons/ReceiptCent.jsx +11 -0
- package/icons/ReceiptEuro.jsx +11 -0
- package/icons/ReceiptIndianRupee.jsx +12 -0
- package/icons/ReceiptJapaneseYen.jsx +13 -0
- package/icons/ReceiptPoundSterling.jsx +12 -0
- package/icons/ReceiptRussianRuble.jsx +11 -0
- package/icons/ReceiptSwissFranc.jsx +12 -0
- package/icons/ReceiptText.jsx +12 -0
- package/icons/ReceiptTurkishLira.jsx +11 -0
- package/icons/RectangleCircle.jsx +10 -0
- package/icons/RectangleEllipsis.jsx +12 -0
- package/icons/RectangleGoggles.jsx +9 -0
- package/icons/RectangleHorizontal.jsx +9 -0
- package/icons/RectangleVertical.jsx +9 -0
- package/icons/Recycle.jsx +14 -0
- package/icons/Redo.jsx +10 -0
- package/icons/Redo2.jsx +10 -0
- package/icons/RedoDot.jsx +11 -0
- package/icons/RefreshCcw.jsx +12 -0
- package/icons/RefreshCcwDot.jsx +13 -0
- package/icons/RefreshCw.jsx +12 -0
- package/icons/RefreshCwOff.jsx +15 -0
- package/icons/Refrigerator.jsx +11 -0
- package/icons/Regex.jsx +12 -0
- package/icons/RemoveFormatting.jsx +13 -0
- package/icons/Repeat.jsx +12 -0
- package/icons/Repeat1.jsx +13 -0
- package/icons/Repeat2.jsx +12 -0
- package/icons/RepeatOff.jsx +15 -0
- package/icons/Replace.jsx +15 -0
- package/icons/ReplaceAll.jsx +17 -0
- package/icons/Reply.jsx +10 -0
- package/icons/ReplyAll.jsx +11 -0
- package/icons/Rewind.jsx +10 -0
- package/icons/Ribbon.jsx +13 -0
- package/icons/Road.jsx +12 -0
- package/icons/Rocket.jsx +12 -0
- package/icons/RockingChair.jsx +12 -0
- package/icons/RollerCoaster.jsx +15 -0
- package/icons/Rose.jsx +13 -0
- package/icons/Rotate3d.jsx +11 -0
- package/icons/RotateCcw.jsx +10 -0
- package/icons/RotateCcwKey.jsx +13 -0
- package/icons/RotateCcwSquare.jsx +11 -0
- package/icons/RotateCw.jsx +10 -0
- package/icons/RotateCwSquare.jsx +11 -0
- package/icons/Route.jsx +11 -0
- package/icons/RouteOff.jsx +15 -0
- package/icons/Router.jsx +14 -0
- package/icons/Rows2.jsx +10 -0
- package/icons/Rows3.jsx +11 -0
- package/icons/Rows4.jsx +12 -0
- package/icons/Rss.jsx +11 -0
- package/icons/Ruler.jsx +13 -0
- package/icons/RulerDimensionLine.jsx +16 -0
- package/icons/RussianRuble.jsx +10 -0
- package/icons/Sailboat.jsx +11 -0
- package/icons/Salad.jsx +13 -0
- package/icons/Sandwich.jsx +13 -0
- package/icons/Satellite.jsx +13 -0
- package/icons/SatelliteDish.jsx +12 -0
- package/icons/SaudiRiyal.jsx +12 -0
- package/icons/Save.jsx +11 -0
- package/icons/SaveAll.jsx +12 -0
- package/icons/SaveOff.jsx +15 -0
- package/icons/Scale.jsx +13 -0
- package/icons/Scale3d.jsx +12 -0
- package/icons/Scaling.jsx +12 -0
- package/icons/Scan.jsx +12 -0
- package/icons/ScanBarcode.jsx +15 -0
- package/icons/ScanEye.jsx +14 -0
- package/icons/ScanFace.jsx +15 -0
- package/icons/ScanHeart.jsx +13 -0
- package/icons/ScanLine.jsx +13 -0
- package/icons/ScanQrCode.jsx +16 -0
- package/icons/ScanSearch.jsx +14 -0
- package/icons/ScanText.jsx +15 -0
- package/icons/School.jsx +14 -0
- package/icons/Scissors.jsx +13 -0
- package/icons/ScissorsLineDashed.jsx +15 -0
- package/icons/Scooter.jsx +12 -0
- package/icons/ScreenShare.jsx +13 -0
- package/icons/ScreenShareOff.jsx +13 -0
- package/icons/Scroll.jsx +10 -0
- package/icons/ScrollText.jsx +12 -0
- package/icons/Search.jsx +10 -0
- package/icons/SearchAlert.jsx +12 -0
- package/icons/SearchCheck.jsx +11 -0
- package/icons/SearchCode.jsx +12 -0
- package/icons/SearchSlash.jsx +11 -0
- package/icons/SearchX.jsx +12 -0
- package/icons/Section.jsx +10 -0
- package/icons/Send.jsx +10 -0
- package/icons/SendHorizontal.jsx +10 -0
- package/icons/SendToBack.jsx +12 -0
- package/icons/SeparatorHorizontal.jsx +11 -0
- package/icons/SeparatorVertical.jsx +11 -0
- package/icons/Server.jsx +12 -0
- package/icons/ServerCog.jsx +20 -0
- package/icons/ServerCrash.jsx +13 -0
- package/icons/ServerOff.jsx +14 -0
- package/icons/Settings.jsx +10 -0
- package/icons/Settings2.jsx +12 -0
- package/icons/Shapes.jsx +11 -0
- package/icons/Share.jsx +11 -0
- package/icons/Share2.jsx +13 -0
- package/icons/Sheet.jsx +13 -0
- package/icons/Shell.jsx +9 -0
- package/icons/ShelvingUnit.jsx +15 -0
- package/icons/Shield.jsx +9 -0
- package/icons/ShieldAlert.jsx +11 -0
- package/icons/ShieldBan.jsx +10 -0
- package/icons/ShieldCheck.jsx +10 -0
- package/icons/ShieldCog.jsx +18 -0
- package/icons/ShieldCogCorner.jsx +18 -0
- package/icons/ShieldEllipsis.jsx +12 -0
- package/icons/ShieldHalf.jsx +10 -0
- package/icons/ShieldMinus.jsx +10 -0
- package/icons/ShieldOff.jsx +11 -0
- package/icons/ShieldPlus.jsx +11 -0
- package/icons/ShieldQuestionMark.jsx +11 -0
- package/icons/ShieldUser.jsx +11 -0
- package/icons/ShieldX.jsx +11 -0
- package/icons/Ship.jsx +13 -0
- package/icons/ShipWheel.jsx +18 -0
- package/icons/Shirt.jsx +9 -0
- package/icons/ShoppingBag.jsx +11 -0
- package/icons/ShoppingBasket.jsx +15 -0
- package/icons/ShoppingCart.jsx +11 -0
- package/icons/Shovel.jsx +11 -0
- package/icons/ShowerHead.jsx +18 -0
- package/icons/Shredder.jsx +15 -0
- package/icons/Shrimp.jsx +13 -0
- package/icons/Shrink.jsx +12 -0
- package/icons/Shrub.jsx +11 -0
- package/icons/Shuffle.jsx +13 -0
- package/icons/Sigma.jsx +9 -0
- package/icons/Signal.jsx +13 -0
- package/icons/SignalHigh.jsx +12 -0
- package/icons/SignalLow.jsx +10 -0
- package/icons/SignalMedium.jsx +11 -0
- package/icons/SignalZero.jsx +9 -0
- package/icons/Signature.jsx +10 -0
- package/icons/Signpost.jsx +11 -0
- package/icons/SignpostBig.jsx +12 -0
- package/icons/Siren.jsx +16 -0
- package/icons/SkipBack.jsx +10 -0
- package/icons/SkipForward.jsx +10 -0
- package/icons/Skull.jsx +12 -0
- package/icons/Slash.jsx +9 -0
- package/icons/Slice.jsx +9 -0
- package/icons/SlidersHorizontal.jsx +17 -0
- package/icons/SlidersVertical.jsx +17 -0
- package/icons/Smartphone.jsx +10 -0
- package/icons/SmartphoneCharging.jsx +10 -0
- package/icons/SmartphoneNfc.jsx +12 -0
- package/icons/Smile.jsx +12 -0
- package/icons/SmilePlus.jsx +14 -0
- package/icons/Snail.jsx +13 -0
- package/icons/Snowflake.jsx +20 -0
- package/icons/SoapDispenserDroplet.jsx +12 -0
- package/icons/Sofa.jsx +13 -0
- package/icons/SolarPanel.jsx +15 -0
- package/icons/Soup.jsx +14 -0
- package/icons/Space.jsx +9 -0
- package/icons/Spade.jsx +10 -0
- package/icons/Sparkle.jsx +9 -0
- package/icons/Sparkles.jsx +12 -0
- package/icons/Speaker.jsx +12 -0
- package/icons/Speech.jsx +11 -0
- package/icons/SpellCheck.jsx +11 -0
- package/icons/SpellCheck2.jsx +11 -0
- package/icons/Spline.jsx +11 -0
- package/icons/SplinePointer.jsx +12 -0
- package/icons/Split.jsx +12 -0
- package/icons/Spool.jsx +10 -0
- package/icons/SportShoe.jsx +11 -0
- package/icons/Spotlight.jsx +13 -0
- package/icons/SprayCan.jsx +18 -0
- package/icons/Sprout.jsx +11 -0
- package/icons/Square.jsx +9 -0
- package/icons/SquareActivity.jsx +10 -0
- package/icons/SquareArrowDown.jsx +11 -0
- package/icons/SquareArrowDownLeft.jsx +11 -0
- package/icons/SquareArrowDownRight.jsx +11 -0
- package/icons/SquareArrowLeft.jsx +11 -0
- package/icons/SquareArrowOutDownLeft.jsx +11 -0
- package/icons/SquareArrowOutDownRight.jsx +11 -0
- package/icons/SquareArrowOutUpLeft.jsx +11 -0
- package/icons/SquareArrowOutUpRight.jsx +11 -0
- package/icons/SquareArrowRight.jsx +11 -0
- package/icons/SquareArrowRightEnter.jsx +11 -0
- package/icons/SquareArrowRightExit.jsx +11 -0
- package/icons/SquareArrowUp.jsx +11 -0
- package/icons/SquareArrowUpLeft.jsx +11 -0
- package/icons/SquareArrowUpRight.jsx +11 -0
- package/icons/SquareAsterisk.jsx +12 -0
- package/icons/SquareBottomDashedScissors.jsx +22 -0
- package/icons/SquareCenterlineDashedHorizontal.jsx +14 -0
- package/icons/SquareCenterlineDashedVertical.jsx +14 -0
- package/icons/SquareChartGantt.jsx +12 -0
- package/icons/SquareCheck.jsx +10 -0
- package/icons/SquareCheckBig.jsx +10 -0
- package/icons/SquareChevronDown.jsx +10 -0
- package/icons/SquareChevronLeft.jsx +10 -0
- package/icons/SquareChevronRight.jsx +10 -0
- package/icons/SquareChevronUp.jsx +10 -0
- package/icons/SquareCode.jsx +11 -0
- package/icons/SquareDashed.jsx +20 -0
- package/icons/SquareDashedBottom.jsx +11 -0
- package/icons/SquareDashedBottomCode.jsx +13 -0
- package/icons/SquareDashedKanban.jsx +23 -0
- package/icons/SquareDashedMousePointer.jsx +18 -0
- package/icons/SquareDashedText.jsx +23 -0
- package/icons/SquareDashedTopSolid.jsx +17 -0
- package/icons/SquareDivide.jsx +12 -0
- package/icons/SquareDot.jsx +10 -0
- package/icons/SquareEqual.jsx +11 -0
- package/icons/SquareFunction.jsx +11 -0
- package/icons/SquareKanban.jsx +12 -0
- package/icons/SquareLibrary.jsx +12 -0
- package/icons/SquareM.jsx +10 -0
- package/icons/SquareMenu.jsx +12 -0
- package/icons/SquareMinus.jsx +10 -0
- package/icons/SquareMousePointer.jsx +10 -0
- package/icons/SquareParking.jsx +10 -0
- package/icons/SquareParkingOff.jsx +13 -0
- package/icons/SquarePause.jsx +11 -0
- package/icons/SquarePen.jsx +10 -0
- package/icons/SquarePercent.jsx +12 -0
- package/icons/SquarePi.jsx +12 -0
- package/icons/SquarePilcrow.jsx +12 -0
- package/icons/SquarePlay.jsx +10 -0
- package/icons/SquarePlus.jsx +11 -0
- package/icons/SquarePower.jsx +11 -0
- package/icons/SquareRadical.jsx +10 -0
- package/icons/SquareRoundCorner.jsx +10 -0
- package/icons/SquareScissors.jsx +14 -0
- package/icons/SquareSigma.jsx +10 -0
- package/icons/SquareSlash.jsx +10 -0
- package/icons/SquareSplitHorizontal.jsx +11 -0
- package/icons/SquareSplitVertical.jsx +11 -0
- package/icons/SquareSquare.jsx +10 -0
- package/icons/SquareStack.jsx +11 -0
- package/icons/SquareStar.jsx +10 -0
- package/icons/SquareStop.jsx +10 -0
- package/icons/SquareTerminal.jsx +11 -0
- package/icons/SquareUser.jsx +11 -0
- package/icons/SquareUserRound.jsx +11 -0
- package/icons/SquareX.jsx +11 -0
- package/icons/SquaresExclude.jsx +10 -0
- package/icons/SquaresIntersect.jsx +19 -0
- package/icons/SquaresSubtract.jsx +14 -0
- package/icons/SquaresUnite.jsx +9 -0
- package/icons/Squircle.jsx +9 -0
- package/icons/SquircleDashed.jsx +16 -0
- package/icons/Squirrel.jsx +12 -0
- package/icons/Stamp.jsx +11 -0
- package/icons/Star.jsx +9 -0
- package/icons/StarHalf.jsx +9 -0
- package/icons/StarOff.jsx +11 -0
- package/icons/StepBack.jsx +10 -0
- package/icons/StepForward.jsx +10 -0
- package/icons/Stethoscope.jsx +13 -0
- package/icons/Sticker.jsx +13 -0
- package/icons/StickyNote.jsx +10 -0
- package/icons/Stone.jsx +11 -0
- package/icons/Store.jsx +11 -0
- package/icons/StretchHorizontal.jsx +10 -0
- package/icons/StretchVertical.jsx +10 -0
- package/icons/Strikethrough.jsx +11 -0
- package/icons/Subscript.jsx +11 -0
- package/icons/Sun.jsx +17 -0
- package/icons/SunDim.jsx +17 -0
- package/icons/SunMedium.jsx +17 -0
- package/icons/SunMoon.jsx +13 -0
- package/icons/SunSnow.jsx +19 -0
- package/icons/Sunrise.jsx +16 -0
- package/icons/Sunset.jsx +16 -0
- package/icons/Superscript.jsx +11 -0
- package/icons/SwatchBook.jsx +12 -0
- package/icons/SwissFranc.jsx +11 -0
- package/icons/SwitchCamera.jsx +13 -0
- package/icons/Sword.jsx +12 -0
- package/icons/Swords.jsx +16 -0
- package/icons/Syringe.jsx +14 -0
- package/icons/Table.jsx +12 -0
- package/icons/Table2.jsx +9 -0
- package/icons/TableCellsMerge.jsx +13 -0
- package/icons/TableCellsSplit.jsx +12 -0
- package/icons/TableColumnsSplit.jsx +19 -0
- package/icons/TableOfContents.jsx +14 -0
- package/icons/TableProperties.jsx +12 -0
- package/icons/TableRowsSplit.jsx +19 -0
- package/icons/Tablet.jsx +10 -0
- package/icons/TabletSmartphone.jsx +11 -0
- package/icons/Tablets.jsx +12 -0
- package/icons/Tag.jsx +10 -0
- package/icons/Tags.jsx +11 -0
- package/icons/Tally1.jsx +9 -0
- package/icons/Tally2.jsx +10 -0
- package/icons/Tally3.jsx +11 -0
- package/icons/Tally4.jsx +12 -0
- package/icons/Tally5.jsx +13 -0
- package/icons/Tangent.jsx +12 -0
- package/icons/Target.jsx +11 -0
- package/icons/Telescope.jsx +15 -0
- package/icons/Tent.jsx +12 -0
- package/icons/TentTree.jsx +15 -0
- package/icons/Terminal.jsx +10 -0
- package/icons/TestTube.jsx +11 -0
- package/icons/TestTubeDiagonal.jsx +11 -0
- package/icons/TestTubes.jsx +14 -0
- package/icons/TextAlignCenter.jsx +11 -0
- package/icons/TextAlignEnd.jsx +11 -0
- package/icons/TextAlignJustify.jsx +11 -0
- package/icons/TextAlignStart.jsx +11 -0
- package/icons/TextCursor.jsx +11 -0
- package/icons/TextCursorInput.jsx +13 -0
- package/icons/TextInitial.jsx +13 -0
- package/icons/TextQuote.jsx +12 -0
- package/icons/TextSearch.jsx +13 -0
- package/icons/TextWrap.jsx +12 -0
- package/icons/Theater.jsx +17 -0
- package/icons/Thermometer.jsx +9 -0
- package/icons/ThermometerSnowflake.jsx +16 -0
- package/icons/ThermometerSun.jsx +14 -0
- package/icons/ThumbsDown.jsx +10 -0
- package/icons/ThumbsUp.jsx +10 -0
- package/icons/Ticket.jsx +12 -0
- package/icons/TicketCheck.jsx +10 -0
- package/icons/TicketMinus.jsx +10 -0
- package/icons/TicketPercent.jsx +12 -0
- package/icons/TicketPlus.jsx +11 -0
- package/icons/TicketSlash.jsx +10 -0
- package/icons/TicketX.jsx +11 -0
- package/icons/Tickets.jsx +13 -0
- package/icons/TicketsPlane.jsx +15 -0
- package/icons/Timeline.jsx +16 -0
- package/icons/Timer.jsx +11 -0
- package/icons/TimerOff.jsx +13 -0
- package/icons/TimerReset.jsx +12 -0
- package/icons/ToggleLeft.jsx +10 -0
- package/icons/ToggleRight.jsx +10 -0
- package/icons/Toilet.jsx +10 -0
- package/icons/ToolCase.jsx +12 -0
- package/icons/Toolbox.jsx +13 -0
- package/icons/Tornado.jsx +13 -0
- package/icons/Torus.jsx +10 -0
- package/icons/Touchpad.jsx +11 -0
- package/icons/TouchpadOff.jsx +14 -0
- package/icons/TowelRack.jsx +11 -0
- package/icons/TowerControl.jsx +15 -0
- package/icons/ToyBrick.jsx +11 -0
- package/icons/Tractor.jsx +17 -0
- package/icons/TrafficCone.jsx +12 -0
- package/icons/TrainFront.jsx +14 -0
- package/icons/TrainFrontTunnel.jsx +15 -0
- package/icons/TrainTrack.jsx +15 -0
- package/icons/TramFront.jsx +15 -0
- package/icons/Transgender.jsx +16 -0
- package/icons/Trash.jsx +11 -0
- package/icons/Trash2.jsx +13 -0
- package/icons/TreeDeciduous.jsx +10 -0
- package/icons/TreePalm.jsx +12 -0
- package/icons/TreePine.jsx +10 -0
- package/icons/Trees.jsx +12 -0
- package/icons/TrendingDown.jsx +10 -0
- package/icons/TrendingUp.jsx +10 -0
- package/icons/TrendingUpDown.jsx +12 -0
- package/icons/Triangle.jsx +9 -0
- package/icons/TriangleAlert.jsx +11 -0
- package/icons/TriangleDashed.jsx +17 -0
- package/icons/TriangleRight.jsx +9 -0
- package/icons/Trophy.jsx +14 -0
- package/icons/Truck.jsx +13 -0
- package/icons/TruckElectric.jsx +15 -0
- package/icons/TurkishLira.jsx +11 -0
- package/icons/Turntable.jsx +12 -0
- package/icons/Turtle.jsx +12 -0
- package/icons/Tv.jsx +10 -0
- package/icons/TvMinimal.jsx +10 -0
- package/icons/TvMinimalPlay.jsx +11 -0
- package/icons/Type.jsx +11 -0
- package/icons/TypeOutline.jsx +9 -0
- package/icons/Umbrella.jsx +11 -0
- package/icons/UmbrellaOff.jsx +13 -0
- package/icons/Underline.jsx +10 -0
- package/icons/Undo.jsx +10 -0
- package/icons/Undo2.jsx +10 -0
- package/icons/UndoDot.jsx +11 -0
- package/icons/UnfoldHorizontal.jsx +16 -0
- package/icons/UnfoldVertical.jsx +16 -0
- package/icons/Ungroup.jsx +10 -0
- package/icons/University.jsx +15 -0
- package/icons/Unlink.jsx +14 -0
- package/icons/Unlink2.jsx +9 -0
- package/icons/Unplug.jsx +14 -0
- package/icons/Upload.jsx +11 -0
- package/icons/Usb.jsx +15 -0
- package/icons/User.jsx +10 -0
- package/icons/UserCheck.jsx +11 -0
- package/icons/UserCog.jsx +19 -0
- package/icons/UserKey.jsx +13 -0
- package/icons/UserLock.jsx +12 -0
- package/icons/UserMinus.jsx +11 -0
- package/icons/UserPen.jsx +11 -0
- package/icons/UserPlus.jsx +12 -0
- package/icons/UserRound.jsx +10 -0
- package/icons/UserRoundCheck.jsx +11 -0
- package/icons/UserRoundCog.jsx +19 -0
- package/icons/UserRoundKey.jsx +13 -0
- package/icons/UserRoundMinus.jsx +11 -0
- package/icons/UserRoundPen.jsx +11 -0
- package/icons/UserRoundPlus.jsx +12 -0
- package/icons/UserRoundSearch.jsx +12 -0
- package/icons/UserRoundX.jsx +12 -0
- package/icons/UserSearch.jsx +12 -0
- package/icons/UserStar.jsx +11 -0
- package/icons/UserX.jsx +12 -0
- package/icons/Users.jsx +12 -0
- package/icons/UsersRound.jsx +11 -0
- package/icons/Utensils.jsx +11 -0
- package/icons/UtensilsCrossed.jsx +12 -0
- package/icons/UtilityPole.jsx +15 -0
- package/icons/Van.jsx +13 -0
- package/icons/Variable.jsx +12 -0
- package/icons/Vault.jsx +18 -0
- package/icons/VectorSquare.jsx +16 -0
- package/icons/Vegan.jsx +11 -0
- package/icons/VenetianMask.jsx +11 -0
- package/icons/Venus.jsx +11 -0
- package/icons/VenusAndMars.jsx +13 -0
- package/icons/Vibrate.jsx +11 -0
- package/icons/VibrateOff.jsx +13 -0
- package/icons/Video.jsx +10 -0
- package/icons/VideoOff.jsx +11 -0
- package/icons/Videotape.jsx +13 -0
- package/icons/View.jsx +12 -0
- package/icons/Voicemail.jsx +11 -0
- package/icons/Volleyball.jsx +14 -0
- package/icons/Volume.jsx +9 -0
- package/icons/Volume1.jsx +10 -0
- package/icons/Volume2.jsx +11 -0
- package/icons/VolumeOff.jsx +13 -0
- package/icons/VolumeX.jsx +11 -0
- package/icons/Vote.jsx +11 -0
- package/icons/Wallet.jsx +10 -0
- package/icons/WalletCards.jsx +11 -0
- package/icons/WalletMinimal.jsx +10 -0
- package/icons/Wallpaper.jsx +13 -0
- package/icons/Wand.jsx +17 -0
- package/icons/WandSparkles.jsx +16 -0
- package/icons/Warehouse.jsx +12 -0
- package/icons/WashingMachine.jsx +13 -0
- package/icons/Watch.jsx +12 -0
- package/icons/WavesArrowDown.jsx +12 -0
- package/icons/WavesArrowUp.jsx +12 -0
- package/icons/WavesHorizontal.jsx +11 -0
- package/icons/WavesLadder.jsx +13 -0
- package/icons/WavesVertical.jsx +11 -0
- package/icons/Waypoints.jsx +15 -0
- package/icons/Webcam.jsx +12 -0
- package/icons/Webhook.jsx +11 -0
- package/icons/WebhookOff.jsx +15 -0
- package/icons/Weight.jsx +10 -0
- package/icons/WeightTilde.jsx +11 -0
- package/icons/Wheat.jsx +16 -0
- package/icons/WheatOff.jsx +18 -0
- package/icons/WholeWord.jsx +13 -0
- package/icons/Wifi.jsx +12 -0
- package/icons/WifiCog.jsx +20 -0
- package/icons/WifiHigh.jsx +11 -0
- package/icons/WifiLow.jsx +10 -0
- package/icons/WifiOff.jsx +15 -0
- package/icons/WifiPen.jsx +12 -0
- package/icons/WifiSync.jsx +15 -0
- package/icons/WifiZero.jsx +9 -0
- package/icons/Wind.jsx +11 -0
- package/icons/WindArrowDown.jsx +12 -0
- package/icons/Wine.jsx +12 -0
- package/icons/WineOff.jsx +13 -0
- package/icons/Workflow.jsx +11 -0
- package/icons/Worm.jsx +11 -0
- package/icons/Wrench.jsx +9 -0
- package/icons/X.jsx +10 -0
- package/icons/XLineTop.jsx +11 -0
- package/icons/Zap.jsx +9 -0
- package/icons/ZapOff.jsx +12 -0
- package/icons/ZodiacAquarius.jsx +10 -0
- package/icons/ZodiacAries.jsx +10 -0
- package/icons/ZodiacCancer.jsx +12 -0
- package/icons/ZodiacCapricorn.jsx +11 -0
- package/icons/ZodiacGemini.jsx +12 -0
- package/icons/ZodiacLeo.jsx +10 -0
- package/icons/ZodiacLibra.jsx +10 -0
- package/icons/ZodiacOphiuchus.jsx +10 -0
- package/icons/ZodiacPisces.jsx +11 -0
- package/icons/ZodiacSagittarius.jsx +11 -0
- package/icons/ZodiacScorpio.jsx +12 -0
- package/icons/ZodiacTaurus.jsx +10 -0
- package/icons/ZodiacVirgo.jsx +12 -0
- package/icons/ZoomIn.jsx +12 -0
- package/icons/ZoomOut.jsx +11 -0
- package/icons/_Icon.jsx +28 -0
- package/icons/index.js +1948 -0
- package/layout/Sidebar.jsx +1 -1
- package/package.json +15 -13
- package/scripts/vendor-icons.js +132 -0
- package/shadcn/lib/clsx.js +25 -0
- package/shadcn/lib/cva.js +47 -0
- package/shadcn/lib/utils.js +1 -1
- package/shadcn/ui/accordion.jsx +1 -1
- package/shadcn/ui/alert.jsx +1 -1
- package/shadcn/ui/badge.jsx +1 -1
- package/shadcn/ui/breadcrumb.jsx +1 -1
- package/shadcn/ui/button-group.jsx +1 -1
- package/shadcn/ui/button.jsx +1 -1
- package/shadcn/ui/calendar.jsx +2 -2
- package/shadcn/ui/carousel.jsx +1 -1
- package/shadcn/ui/checkbox.jsx +1 -1
- package/shadcn/ui/command.jsx +2 -2
- package/shadcn/ui/context-menu.jsx +1 -1
- package/shadcn/ui/dialog.jsx +1 -1
- package/shadcn/ui/dropdown-menu.jsx +1 -1
- package/shadcn/ui/empty.jsx +1 -1
- package/shadcn/ui/field.jsx +1 -1
- package/shadcn/ui/input-group.jsx +1 -1
- package/shadcn/ui/item.jsx +1 -1
- package/shadcn/ui/menubar.jsx +1 -1
- package/shadcn/ui/navigation-menu.jsx +2 -2
- package/shadcn/ui/pagination.jsx +1 -1
- package/shadcn/ui/radio-group.jsx +1 -1
- package/shadcn/ui/select.jsx +1 -1
- package/shadcn/ui/sheet.jsx +1 -1
- package/shadcn/ui/sidebar.jsx +2 -2
- package/shadcn/ui/spinner.jsx +1 -1
- package/shadcn/ui/tabs.jsx +1 -1
- package/shadcn/ui/toggle.jsx +1 -1
- package/stevederico-skateboard-ui-3.0.1.tgz +0 -0
- package/styles.css +68 -1
- package/views/LandingView.jsx +2 -2
- package/views/SettingsView.jsx +2 -2
- package/.claude/settings.local.json +0 -16
- package/.playwright-mcp/dark-mode-borders.png +0 -0
- package/.playwright-mcp/dark-mode-inputs.png +0 -0
- package/.playwright-mcp/dark-sidebar.png +0 -0
- package/.playwright-mcp/features-centered-v2.png +0 -0
- package/.playwright-mcp/features-centered-v3.png +0 -0
- package/.playwright-mcp/features-centered.png +0 -0
- package/.playwright-mcp/features-check.png +0 -0
- package/.playwright-mcp/landing-dark.png +0 -0
- package/.playwright-mcp/light-mode-borders.png +0 -0
- package/.playwright-mcp/sidebar-dark-mode.png +0 -0
- package/.playwright-mcp/sidebar-light-mode.png +0 -0
- package/.playwright-mcp/signin-dark.png +0 -0
- /package/{shadcn → .claude/worktrees/strange-feistel-abc494/shadcn}/ui/sonner.jsx +0 -0
|
@@ -0,0 +1,1252 @@
|
|
|
1
|
+
# skateboard-ui
|
|
2
|
+
|
|
3
|
+
React component library for rapid application development. Built with TailwindCSS v4 and shadcn/ui.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# npm
|
|
9
|
+
npm install @stevederico/skateboard-ui
|
|
10
|
+
|
|
11
|
+
# deno
|
|
12
|
+
deno install npm:@stevederico/skateboard-ui
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import './assets/styles.css';
|
|
19
|
+
import { createSkateboardApp } from '@stevederico/skateboard-ui/App';
|
|
20
|
+
import constants from './constants.json';
|
|
21
|
+
import HomeView from './components/HomeView.jsx';
|
|
22
|
+
|
|
23
|
+
const appRoutes = [
|
|
24
|
+
{ path: 'home', element: <HomeView /> }
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
createSkateboardApp({ constants, appRoutes });
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
That's it! You get routing, auth, layout, landing page, settings, and payments.
|
|
31
|
+
|
|
32
|
+
## Dark Mode Setup
|
|
33
|
+
|
|
34
|
+
To prevent flash of unstyled content (FOUC) when using dark mode, add this script to your `index.html` **before** your app loads:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<!DOCTYPE html>
|
|
38
|
+
<html lang="en">
|
|
39
|
+
<head>
|
|
40
|
+
<meta charset="UTF-8" />
|
|
41
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
42
|
+
|
|
43
|
+
<!-- Prevent dark mode FOUC -->
|
|
44
|
+
<script>
|
|
45
|
+
try {
|
|
46
|
+
const theme = localStorage.getItem('theme');
|
|
47
|
+
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
48
|
+
if (theme === 'dark' || (!theme && systemDark)) {
|
|
49
|
+
document.documentElement.classList.add('dark');
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<title>Your App</title>
|
|
55
|
+
</head>
|
|
56
|
+
<body>
|
|
57
|
+
<div id="root"></div>
|
|
58
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
59
|
+
</body>
|
|
60
|
+
</html>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This ensures the correct theme is applied before React renders, eliminating any flash between light and dark modes.
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
skateboard-ui requires a `constants` object that configures your application:
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// constants.json or constants.js
|
|
71
|
+
const constants = {
|
|
72
|
+
// Required: Backend URLs (include /api prefix)
|
|
73
|
+
devBackendURL: "http://localhost:8000/api",
|
|
74
|
+
backendURL: "https://api.myapp.com/api",
|
|
75
|
+
|
|
76
|
+
// Required: App identity
|
|
77
|
+
appName: "MyApp",
|
|
78
|
+
appIcon: "sparkles", // Lucide icon name
|
|
79
|
+
|
|
80
|
+
// Required: Landing page content
|
|
81
|
+
tagline: "Build apps faster with skateboard-ui",
|
|
82
|
+
cta: "Get Started",
|
|
83
|
+
|
|
84
|
+
// Required: Features section
|
|
85
|
+
features: {
|
|
86
|
+
title: "Everything you need",
|
|
87
|
+
items: [
|
|
88
|
+
{ icon: "Zap", title: "Fast", description: "Built for speed" },
|
|
89
|
+
{ icon: "Shield", title: "Secure", description: "Authentication included" }
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// Required: Company information
|
|
94
|
+
companyName: "Your Company",
|
|
95
|
+
companyWebsite: "https://yourcompany.com",
|
|
96
|
+
companyEmail: "hello@yourcompany.com",
|
|
97
|
+
|
|
98
|
+
// Optional: Navigation pages (sidebar + tabbar)
|
|
99
|
+
pages: [
|
|
100
|
+
{ title: "Home", icon: "home", url: "home" },
|
|
101
|
+
{ title: "Search", icon: "search", url: "search" }
|
|
102
|
+
],
|
|
103
|
+
|
|
104
|
+
// Optional: Authentication
|
|
105
|
+
noLogin: false, // Set true to disable authentication entirely
|
|
106
|
+
authOverlay: false, // Set true to allow unauthenticated /app access (use with useAuthGate)
|
|
107
|
+
|
|
108
|
+
// Optional: UI visibility
|
|
109
|
+
hideSidebar: false,
|
|
110
|
+
hideTabBar: false,
|
|
111
|
+
hideSidebarHeader: false,
|
|
112
|
+
|
|
113
|
+
// Optional: Payments (Stripe)
|
|
114
|
+
stripeProducts: [
|
|
115
|
+
{
|
|
116
|
+
name: "Pro Plan",
|
|
117
|
+
priceId: "price_123",
|
|
118
|
+
price: "$10/month",
|
|
119
|
+
lookup_key: "pro_plan",
|
|
120
|
+
title: "Go Pro",
|
|
121
|
+
interval: "month",
|
|
122
|
+
features: ["Unlimited usage", "Priority support", "Advanced features"]
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
|
|
126
|
+
// Optional: Landing page customization
|
|
127
|
+
navLinks: [ // Override header nav links
|
|
128
|
+
{ label: "Features", href: "#features" },
|
|
129
|
+
{ label: "Pricing", href: "#pricing" },
|
|
130
|
+
{ label: "Blog", href: "/blog" }
|
|
131
|
+
],
|
|
132
|
+
pricing: {
|
|
133
|
+
title: "Simple Pricing", // Pricing section heading
|
|
134
|
+
extras: ["Priority Customer Support", "Cancel anytime"] // Extra bullets after product features
|
|
135
|
+
},
|
|
136
|
+
ctaHeading: "Ready To Build?", // CTA section heading
|
|
137
|
+
footerLinks: [ // Override footer links
|
|
138
|
+
{ label: "Privacy", href: "/privacy" },
|
|
139
|
+
{ label: "Terms", href: "/terms" },
|
|
140
|
+
{ label: "EULA", href: "/eula" }
|
|
141
|
+
],
|
|
142
|
+
copyrightText: "All rights reserved.", // Copyright suffix after "© {year} {companyName}."
|
|
143
|
+
|
|
144
|
+
// Optional: Legal documents (plain text, supports _COMPANY_, _WEBSITE_, _EMAIL_ placeholders)
|
|
145
|
+
termsOfService: "Terms of Service for _COMPANY_...",
|
|
146
|
+
privacyPolicy: "Privacy Policy for _COMPANY_...",
|
|
147
|
+
EULA: "End User License Agreement...",
|
|
148
|
+
subscriptionDetails: "Subscription details...",
|
|
149
|
+
|
|
150
|
+
// Optional: App metadata
|
|
151
|
+
version: "1.0.0"
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Backend URL Pattern
|
|
156
|
+
|
|
157
|
+
The `devBackendURL` and `backendURL` should include your full API base path (including the `/api` prefix):
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
const constants = {
|
|
161
|
+
devBackendURL: "http://localhost:8000/api", // Include /api prefix
|
|
162
|
+
backendURL: "https://api.myapp.com/api",
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Endpoints are relative to this base URL:
|
|
167
|
+
- `${getBackendURL()}/signup` → `http://localhost:8000/api/signup`
|
|
168
|
+
- `${getBackendURL()}/me` → `http://localhost:8000/api/me`
|
|
169
|
+
- `${getBackendURL()}/deals` → `http://localhost:8000/api/deals`
|
|
170
|
+
|
|
171
|
+
**Tip:** Include API versioning in the base URL (e.g., `/api/v2`) rather than in each endpoint path.
|
|
172
|
+
|
|
173
|
+
## createSkateboardApp
|
|
174
|
+
|
|
175
|
+
The bootstrap function that sets up routing, auth, theming, state, toasts, and error handling.
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
import { createSkateboardApp } from '@stevederico/skateboard-ui/App';
|
|
179
|
+
|
|
180
|
+
createSkateboardApp({
|
|
181
|
+
constants, // Required: App configuration object
|
|
182
|
+
appRoutes, // Required: [{ path: string, element: JSX.Element }]
|
|
183
|
+
defaultRoute, // Optional: Default route path (defaults to first appRoute path)
|
|
184
|
+
landingPage, // Optional: Custom landing page JSX element
|
|
185
|
+
wrapper, // Optional: React component to wrap the router (e.g., for providers)
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### What It Sets Up
|
|
190
|
+
|
|
191
|
+
- **Routes:** Landing, signin, signup, signout, app routes, settings, payment, legal pages (terms, privacy, EULA, subscription)
|
|
192
|
+
- **Authentication:** ProtectedRoute wrapping `/app/*`, AuthOverlay for lazy auth
|
|
193
|
+
- **Theming:** next-themes ThemeProvider with system theme support
|
|
194
|
+
- **State:** ContextProvider with user, UI, and auth overlay state
|
|
195
|
+
- **Toasts:** Sonner Toaster (top-right, rich colors, close button)
|
|
196
|
+
- **Error Boundary:** Catches render errors, unhandled rejections, and global errors
|
|
197
|
+
|
|
198
|
+
### Generated Routes
|
|
199
|
+
|
|
200
|
+
| Route | Component | Protected |
|
|
201
|
+
|-------|-----------|-----------|
|
|
202
|
+
| `/` | LandingView (or custom `landingPage`) | No |
|
|
203
|
+
| `/signin` | SignInView | No |
|
|
204
|
+
| `/signup` | SignUpView | No |
|
|
205
|
+
| `/signout` | SignOutView | No |
|
|
206
|
+
| `/app/:path` | Your appRoutes | Yes |
|
|
207
|
+
| `/app/settings` | SettingsView | Yes |
|
|
208
|
+
| `/app/payment` | PaymentView | Yes |
|
|
209
|
+
| `/terms` | TextView | No |
|
|
210
|
+
| `/privacy` | TextView | No |
|
|
211
|
+
| `/eula` | TextView | No |
|
|
212
|
+
| `/subscription` | TextView | No |
|
|
213
|
+
| `*` | NotFound | No |
|
|
214
|
+
|
|
215
|
+
## Authentication
|
|
216
|
+
|
|
217
|
+
### Overview
|
|
218
|
+
|
|
219
|
+
skateboard-ui uses a **hybrid cookie + localStorage authentication system** that combines security with performance:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Frontend Backend Storage
|
|
223
|
+
──────── ─────── ───────
|
|
224
|
+
|
|
225
|
+
1. POST /signin → Validate credentials
|
|
226
|
+
credentials
|
|
227
|
+
← Set-Cookie: {appName}_token (HttpOnly)
|
|
228
|
+
← Set-Cookie: csrf_token
|
|
229
|
+
← Response: { csrfToken, ...user }
|
|
230
|
+
|
|
231
|
+
2. Extract tokens → localStorage:
|
|
232
|
+
- CSRF from cookie {appName}_csrf
|
|
233
|
+
- User from response {appName}_user
|
|
234
|
+
|
|
235
|
+
3. isAuthenticated() → Check localStorage
|
|
236
|
+
(client-side) (fast, no network)
|
|
237
|
+
|
|
238
|
+
4. ProtectedRoute → GET /me
|
|
239
|
+
(server validation) Validate cookies
|
|
240
|
+
← 200 OK or 401 Unauthorized
|
|
241
|
+
|
|
242
|
+
5. API requests → Protected endpoints
|
|
243
|
+
+ cookies (automatic) Validate {appName}_token
|
|
244
|
+
+ X-CSRF-Token header Validate CSRF header
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Cookie-Based Session Management
|
|
248
|
+
- **Session token** stored in `{appName}_token` cookie (HttpOnly, Secure, SameSite=Strict)
|
|
249
|
+
- Automatically sent with every request via browser
|
|
250
|
+
- Cannot be accessed by JavaScript (XSS protection)
|
|
251
|
+
- Backend validates cookie on each protected endpoint
|
|
252
|
+
|
|
253
|
+
### localStorage for Client-Side Validation
|
|
254
|
+
- **CSRF token** and **user data** stored in localStorage
|
|
255
|
+
- Enables instant `isAuthenticated()` checks without network calls
|
|
256
|
+
- Used by client-side routing logic (ProtectedRoute initial check)
|
|
257
|
+
- Not used for actual authentication (cookies handle that)
|
|
258
|
+
|
|
259
|
+
### CSRF Protection
|
|
260
|
+
- Dual-token system prevents CSRF attacks
|
|
261
|
+
- **CSRF token** sent in `X-CSRF-Token` header with state-changing requests
|
|
262
|
+
- Backend validates header matches stored session CSRF token
|
|
263
|
+
- Separate from session cookie to prevent cookie-based CSRF
|
|
264
|
+
|
|
265
|
+
### CSRF Error Handling
|
|
266
|
+
|
|
267
|
+
The `apiRequest` utility automatically handles CSRF token failures:
|
|
268
|
+
|
|
269
|
+
1. **Auto-Regeneration**: Backend auto-regenerates tokens after server restart
|
|
270
|
+
2. **Retry Logic**: Frontend automatically retries failed requests once after refreshing the session
|
|
271
|
+
3. **User Experience**: Transparent recovery without forcing sign-out or page refresh
|
|
272
|
+
|
|
273
|
+
**Error Flow**:
|
|
274
|
+
```
|
|
275
|
+
POST /api/keys → 403 CSRF error
|
|
276
|
+
↓
|
|
277
|
+
Fetch /me (triggers backend auto-regeneration)
|
|
278
|
+
↓
|
|
279
|
+
Retry POST /api/keys with fresh token
|
|
280
|
+
↓
|
|
281
|
+
Success
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Required Backend Endpoints
|
|
285
|
+
|
|
286
|
+
#### POST /signup
|
|
287
|
+
Create new user account.
|
|
288
|
+
|
|
289
|
+
**Request:**
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"email": "user@example.com",
|
|
293
|
+
"password": "securePassword123",
|
|
294
|
+
"name": "John Doe"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Response:**
|
|
299
|
+
- Status: 201 Created
|
|
300
|
+
- Headers:
|
|
301
|
+
- `Set-Cookie: {appName}_token={sessionToken}; HttpOnly; Secure; SameSite=Strict; Path=/`
|
|
302
|
+
- `Set-Cookie: csrf_token={csrfToken}; Secure; SameSite=Lax; Path=/`
|
|
303
|
+
- Body:
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"csrfToken": "csrf_abc123...",
|
|
307
|
+
"user": {
|
|
308
|
+
"id": "user123",
|
|
309
|
+
"email": "user@example.com",
|
|
310
|
+
"name": "John Doe"
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### POST /signin
|
|
316
|
+
Authenticate existing user.
|
|
317
|
+
|
|
318
|
+
**Request:**
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"email": "user@example.com",
|
|
322
|
+
"password": "securePassword123"
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Response:**
|
|
327
|
+
- Status: 200 OK
|
|
328
|
+
- Headers: Same as /signup
|
|
329
|
+
- Body: Same as /signup
|
|
330
|
+
|
|
331
|
+
#### GET /me
|
|
332
|
+
Validate current session and return user data.
|
|
333
|
+
|
|
334
|
+
**Request:**
|
|
335
|
+
- Headers: Cookies automatically sent by browser
|
|
336
|
+
|
|
337
|
+
**Response (authenticated):**
|
|
338
|
+
- Status: 200 OK
|
|
339
|
+
- Body:
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"user": {
|
|
343
|
+
"id": "user123",
|
|
344
|
+
"email": "user@example.com",
|
|
345
|
+
"name": "John Doe",
|
|
346
|
+
"subscription": {
|
|
347
|
+
"status": "active",
|
|
348
|
+
"expires": 1735689600,
|
|
349
|
+
"stripeID": "cus_abc123"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Response (not authenticated):**
|
|
356
|
+
- Status: 401 Unauthorized
|
|
357
|
+
|
|
358
|
+
#### POST /signout
|
|
359
|
+
End current session.
|
|
360
|
+
|
|
361
|
+
**Request:**
|
|
362
|
+
- Headers:
|
|
363
|
+
- Cookies automatically sent
|
|
364
|
+
- `X-CSRF-Token: {csrfToken}`
|
|
365
|
+
|
|
366
|
+
**Response:**
|
|
367
|
+
- Status: 200 OK
|
|
368
|
+
- Headers:
|
|
369
|
+
- `Set-Cookie: {appName}_token=; Max-Age=0; Path=/` (clear cookie)
|
|
370
|
+
- `Set-Cookie: csrf_token=; Max-Age=0; Path=/` (clear cookie)
|
|
371
|
+
|
|
372
|
+
### Optional Backend Endpoints
|
|
373
|
+
|
|
374
|
+
#### POST /usage
|
|
375
|
+
Track and check feature usage limits.
|
|
376
|
+
|
|
377
|
+
**Request:**
|
|
378
|
+
```json
|
|
379
|
+
{ "operation": "check" }
|
|
380
|
+
```
|
|
381
|
+
or
|
|
382
|
+
```json
|
|
383
|
+
{ "operation": "track" }
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**Response:**
|
|
387
|
+
```json
|
|
388
|
+
{ "remaining": 15, "total": 20, "isSubscriber": false }
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### GET /isSubscriber
|
|
392
|
+
Check subscription status.
|
|
393
|
+
|
|
394
|
+
**Response:**
|
|
395
|
+
```json
|
|
396
|
+
{ "isSubscriber": true }
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### POST /checkout (Stripe)
|
|
400
|
+
Create a Stripe checkout session.
|
|
401
|
+
|
|
402
|
+
**Request:**
|
|
403
|
+
```json
|
|
404
|
+
{ "lookup_key": "pro_plan", "email": "user@example.com" }
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Response:**
|
|
408
|
+
```json
|
|
409
|
+
{ "url": "https://checkout.stripe.com/..." }
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### POST /portal (Stripe)
|
|
413
|
+
Open Stripe billing portal.
|
|
414
|
+
|
|
415
|
+
**Request:**
|
|
416
|
+
```json
|
|
417
|
+
{ "customerID": "cus_abc123" }
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Response:**
|
|
421
|
+
```json
|
|
422
|
+
{ "url": "https://billing.stripe.com/..." }
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Cookie Configuration
|
|
426
|
+
|
|
427
|
+
**Session Token Cookie:**
|
|
428
|
+
```javascript
|
|
429
|
+
{
|
|
430
|
+
name: '{appName}_token',
|
|
431
|
+
httpOnly: true, // Prevents JavaScript access (XSS protection)
|
|
432
|
+
secure: true, // HTTPS only (production)
|
|
433
|
+
sameSite: 'Strict', // Strongest CSRF protection
|
|
434
|
+
path: '/',
|
|
435
|
+
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days (configurable)
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
**CSRF Token Cookie:**
|
|
440
|
+
```javascript
|
|
441
|
+
{
|
|
442
|
+
name: 'csrf_token',
|
|
443
|
+
httpOnly: false, // Must be readable by JavaScript
|
|
444
|
+
secure: true, // HTTPS only (production)
|
|
445
|
+
sameSite: 'Lax', // Allow top-level navigation
|
|
446
|
+
path: '/',
|
|
447
|
+
maxAge: 7 * 24 * 60 * 60 * 1000 // Match session token
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Protected Endpoints
|
|
452
|
+
All authenticated endpoints must:
|
|
453
|
+
1. Validate `{appName}_token` cookie exists and is valid
|
|
454
|
+
2. For state-changing operations (POST, PUT, DELETE), validate `X-CSRF-Token` header
|
|
455
|
+
3. Return 401 if authentication fails
|
|
456
|
+
4. Return 403 if CSRF validation fails
|
|
457
|
+
|
|
458
|
+
### Security Considerations
|
|
459
|
+
|
|
460
|
+
- **XSS Protection**: Session token is HttpOnly — JavaScript cannot access it
|
|
461
|
+
- **CSRF Protection**: Dual-token pattern prevents cookie-based CSRF attacks
|
|
462
|
+
- **SameSite Policy**: Session token (Strict), CSRF token (Lax)
|
|
463
|
+
- **HTTPS Requirement**: All cookies marked `Secure` in production
|
|
464
|
+
- **localStorage Trade-offs**: Acceptable for CSRF token (cannot authenticate alone), never store session token
|
|
465
|
+
|
|
466
|
+
### Example Backend Implementation (Express.js)
|
|
467
|
+
|
|
468
|
+
```javascript
|
|
469
|
+
import express from 'express';
|
|
470
|
+
import cookieParser from 'cookie-parser';
|
|
471
|
+
import crypto from 'crypto';
|
|
472
|
+
|
|
473
|
+
const app = express();
|
|
474
|
+
app.use(express.json());
|
|
475
|
+
app.use(cookieParser());
|
|
476
|
+
|
|
477
|
+
// In-memory session store (use Redis in production)
|
|
478
|
+
const sessions = new Map();
|
|
479
|
+
|
|
480
|
+
function generateToken() {
|
|
481
|
+
return crypto.randomBytes(32).toString('hex');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function requireAuth(req, res, next) {
|
|
485
|
+
const sessionToken = req.cookies.myapp_token;
|
|
486
|
+
const session = sessions.get(sessionToken);
|
|
487
|
+
if (!session) return res.status(401).json({ error: 'Not authenticated' });
|
|
488
|
+
req.session = session;
|
|
489
|
+
next();
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function requireCSRF(req, res, next) {
|
|
493
|
+
const csrfToken = req.headers['x-csrf-token'];
|
|
494
|
+
if (!req.session || req.session.csrfToken !== csrfToken) {
|
|
495
|
+
return res.status(403).json({ error: 'Invalid CSRF token' });
|
|
496
|
+
}
|
|
497
|
+
next();
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
app.post('/api/signup', async (req, res) => {
|
|
501
|
+
const { email, password, name } = req.body;
|
|
502
|
+
if (!email || !password) return res.status(400).json({ error: 'Email and password required' });
|
|
503
|
+
|
|
504
|
+
const user = await createUser(email, password, name);
|
|
505
|
+
const sessionToken = generateToken();
|
|
506
|
+
const csrfToken = generateToken();
|
|
507
|
+
|
|
508
|
+
sessions.set(sessionToken, { userId: user.id, csrfToken, createdAt: Date.now() });
|
|
509
|
+
|
|
510
|
+
res.cookie('myapp_token', sessionToken, {
|
|
511
|
+
httpOnly: true, secure: process.env.NODE_ENV === 'production',
|
|
512
|
+
sameSite: 'strict', maxAge: 7 * 24 * 60 * 60 * 1000
|
|
513
|
+
});
|
|
514
|
+
res.cookie('csrf_token', csrfToken, {
|
|
515
|
+
httpOnly: false, secure: process.env.NODE_ENV === 'production',
|
|
516
|
+
sameSite: 'lax', maxAge: 7 * 24 * 60 * 60 * 1000
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
res.status(201).json({ csrfToken, user: { id: user.id, email: user.email, name: user.name } });
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
app.get('/api/me', requireAuth, async (req, res) => {
|
|
523
|
+
const user = await getUserById(req.session.userId);
|
|
524
|
+
res.json({ user: { id: user.id, email: user.email, name: user.name } });
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
app.post('/api/signout', requireAuth, requireCSRF, (req, res) => {
|
|
528
|
+
sessions.delete(req.cookies.myapp_token);
|
|
529
|
+
res.clearCookie('myapp_token');
|
|
530
|
+
res.clearCookie('csrf_token');
|
|
531
|
+
res.json({ message: 'Signed out successfully' });
|
|
532
|
+
});
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Auth Troubleshooting
|
|
536
|
+
|
|
537
|
+
| Problem | Cause | Fix |
|
|
538
|
+
|---------|-------|-----|
|
|
539
|
+
| "Not authenticated" after signin | Cookies not sent | Verify `credentials: 'include'` in fetch calls |
|
|
540
|
+
| CSRF 403 errors | Token mismatch | Check `X-CSRF-Token` header, verify cookie exists |
|
|
541
|
+
| Cookies not persisting | SameSite/Secure flags | Set `secure: false` in dev, check domain match |
|
|
542
|
+
| `isAuthenticated()` false but cookie exists | localStorage cleared | Re-fetch from `/me` endpoint |
|
|
543
|
+
|
|
544
|
+
### No-Login Mode
|
|
545
|
+
|
|
546
|
+
```javascript
|
|
547
|
+
const constants = { noLogin: true };
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Effects: `isAuthenticated()` always returns `true`, ProtectedRoute allows all access.
|
|
551
|
+
|
|
552
|
+
## Components
|
|
553
|
+
|
|
554
|
+
### Core Components
|
|
555
|
+
|
|
556
|
+
| Component | Import | Description |
|
|
557
|
+
|-----------|--------|-------------|
|
|
558
|
+
| Sidebar | `@stevederico/skateboard-ui/Sidebar` | Desktop navigation sidebar with collapsible icon mode |
|
|
559
|
+
| Header | `@stevederico/skateboard-ui/Header` | App header with title and action button |
|
|
560
|
+
| Layout | `@stevederico/skateboard-ui/Layout` | Page layout with sidebar (desktop) and tabbar (mobile) |
|
|
561
|
+
| TabBar | `@stevederico/skateboard-ui/TabBar` | Mobile bottom navigation with labels |
|
|
562
|
+
| DynamicIcon | `@stevederico/skateboard-ui/DynamicIcon` | Lucide icon by name string |
|
|
563
|
+
| ThemeToggle | `@stevederico/skateboard-ui/ThemeToggle` | Dark/light mode toggle button |
|
|
564
|
+
| Sheet | `@stevederico/skateboard-ui/Sheet` | Slide-out panel |
|
|
565
|
+
| UpgradeSheet | `@stevederico/skateboard-ui/UpgradeSheet` | Premium upgrade drawer |
|
|
566
|
+
| ErrorBoundary | `@stevederico/skateboard-ui/ErrorBoundary` | Error boundary wrapper |
|
|
567
|
+
|
|
568
|
+
### View Components
|
|
569
|
+
|
|
570
|
+
| Component | Import | Description |
|
|
571
|
+
|-----------|--------|-------------|
|
|
572
|
+
| LandingView | `@stevederico/skateboard-ui/LandingView` | Landing page with hero, features, pricing |
|
|
573
|
+
| LandingViewSimple | `@stevederico/skateboard-ui/LandingViewSimple` | Minimal landing page |
|
|
574
|
+
| SignInView | `@stevederico/skateboard-ui/SignInView` | Sign in form with Card layout |
|
|
575
|
+
| SignUpView | `@stevederico/skateboard-ui/SignUpView` | Sign up form with password validation |
|
|
576
|
+
| SignOutView | `@stevederico/skateboard-ui/SignOutView` | Sign out handler with redirect |
|
|
577
|
+
| SettingsView | `@stevederico/skateboard-ui/SettingsView` | User settings, billing, theme |
|
|
578
|
+
| PaymentView | `@stevederico/skateboard-ui/PaymentView` | Stripe payment redirect handler |
|
|
579
|
+
| TextView | `@stevederico/skateboard-ui/TextView` | Legal document viewer with placeholder replacement |
|
|
580
|
+
| NotFound | `@stevederico/skateboard-ui/NotFound` | 404 page |
|
|
581
|
+
|
|
582
|
+
### Auth Components
|
|
583
|
+
|
|
584
|
+
| Export | Import | Description |
|
|
585
|
+
|--------|--------|-------------|
|
|
586
|
+
| AuthOverlay | `@stevederico/skateboard-ui/AuthOverlay` | Modal sign-in/sign-up dialog |
|
|
587
|
+
| useAuthGate | `@stevederico/skateboard-ui/useAuthGate` | Hook to gate actions behind auth |
|
|
588
|
+
|
|
589
|
+
### State & Utilities
|
|
590
|
+
|
|
591
|
+
| Export | Import | Description |
|
|
592
|
+
|--------|--------|-------------|
|
|
593
|
+
| Context | `@stevederico/skateboard-ui/Context` | App state provider and accessor |
|
|
594
|
+
| Utilities | `@stevederico/skateboard-ui/Utilities` | API, auth, formatting, and UI utilities |
|
|
595
|
+
| App | `@stevederico/skateboard-ui/App` | createSkateboardApp bootstrap function |
|
|
596
|
+
| ProtectedRoute | `@stevederico/skateboard-ui/ProtectedRoute` | Route guard with server validation |
|
|
597
|
+
|
|
598
|
+
## Component Details
|
|
599
|
+
|
|
600
|
+
### Sidebar
|
|
601
|
+
|
|
602
|
+
Desktop navigation sidebar with collapsible icon mode, user dropdown, and settings link.
|
|
603
|
+
|
|
604
|
+
```javascript
|
|
605
|
+
import Sidebar from '@stevederico/skateboard-ui/Sidebar';
|
|
606
|
+
|
|
607
|
+
// Used internally by Layout. Renders automatically based on constants.
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Reads from constants:**
|
|
611
|
+
- `pages` — Navigation items rendered as sidebar menu buttons
|
|
612
|
+
- `appName` — Displayed in sidebar header
|
|
613
|
+
- `appIcon` — Icon in sidebar header
|
|
614
|
+
- `hideSidebarHeader` — Hides the header when `true`
|
|
615
|
+
|
|
616
|
+
**Features:**
|
|
617
|
+
- Collapsible to icon-only mode via rail
|
|
618
|
+
- Active page highlighting based on current route
|
|
619
|
+
- Tooltip labels when collapsed
|
|
620
|
+
- Footer with Settings button and user dropdown (account, billing, notifications, sign out)
|
|
621
|
+
|
|
622
|
+
### Header
|
|
623
|
+
|
|
624
|
+
```javascript
|
|
625
|
+
import Header from '@stevederico/skateboard-ui/Header';
|
|
626
|
+
|
|
627
|
+
<Header
|
|
628
|
+
title="Dashboard"
|
|
629
|
+
buttonTitle="Add"
|
|
630
|
+
onButtonTitleClick={() => console.log('clicked')}
|
|
631
|
+
buttonClass="bg-app text-white"
|
|
632
|
+
className="sticky top-0"
|
|
633
|
+
>
|
|
634
|
+
{/* Optional: custom right-side content */}
|
|
635
|
+
</Header>
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Props:**
|
|
639
|
+
|
|
640
|
+
| Prop | Type | Default | Description |
|
|
641
|
+
|------|------|---------|-------------|
|
|
642
|
+
| title | string | required | Header title |
|
|
643
|
+
| buttonTitle | string | — | Action button text (omit to hide) |
|
|
644
|
+
| onButtonTitleClick | function | — | Button click handler |
|
|
645
|
+
| buttonClass | string | — | Additional button CSS classes |
|
|
646
|
+
| className | string | — | Additional header CSS classes |
|
|
647
|
+
| children | ReactNode | — | Custom right-side content |
|
|
648
|
+
|
|
649
|
+
### DynamicIcon
|
|
650
|
+
|
|
651
|
+
Renders a Lucide icon by name string. Accepts kebab-case, snake_case, or PascalCase.
|
|
652
|
+
|
|
653
|
+
```javascript
|
|
654
|
+
import DynamicIcon from '@stevederico/skateboard-ui/DynamicIcon';
|
|
655
|
+
|
|
656
|
+
<DynamicIcon name="home" size={24} />
|
|
657
|
+
<DynamicIcon name="arrow-right" size={20} color="red" />
|
|
658
|
+
<DynamicIcon name="settings" className="text-muted-foreground" />
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**Props:**
|
|
662
|
+
|
|
663
|
+
| Prop | Type | Default | Description |
|
|
664
|
+
|------|------|---------|-------------|
|
|
665
|
+
| name | string | required | Icon name (e.g. "home", "arrow-right", "Settings") |
|
|
666
|
+
| size | number | 24 | Icon size in pixels |
|
|
667
|
+
| color | string | 'currentColor' | Stroke color |
|
|
668
|
+
| strokeWidth | number | 2 | Stroke width |
|
|
669
|
+
| className | string | — | Additional CSS classes |
|
|
670
|
+
|
|
671
|
+
Icons from [lucide-react](https://lucide.dev/icons/). Returns null if icon name not found.
|
|
672
|
+
|
|
673
|
+
### ThemeToggle
|
|
674
|
+
|
|
675
|
+
```javascript
|
|
676
|
+
import ThemeToggle from '@stevederico/skateboard-ui/ThemeToggle';
|
|
677
|
+
|
|
678
|
+
<ThemeToggle />
|
|
679
|
+
<ThemeToggle variant="landing" iconSize={18} />
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**Props:**
|
|
683
|
+
|
|
684
|
+
| Prop | Type | Default | Description |
|
|
685
|
+
|------|------|---------|-------------|
|
|
686
|
+
| className | string | "" | Additional CSS classes |
|
|
687
|
+
| iconSize | number | 16 | Icon size in pixels |
|
|
688
|
+
| variant | string | "settings" | "settings" (ghost) or "landing" (outline) |
|
|
689
|
+
|
|
690
|
+
### TabBar
|
|
691
|
+
|
|
692
|
+
Mobile bottom navigation bar. Hidden on `md+` screens. Renders pages from `constants.pages` plus a Settings link.
|
|
693
|
+
|
|
694
|
+
```javascript
|
|
695
|
+
import TabBar from '@stevederico/skateboard-ui/TabBar';
|
|
696
|
+
|
|
697
|
+
// Used internally by Layout. Renders automatically.
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
**Features:**
|
|
701
|
+
- Fixed bottom position on mobile
|
|
702
|
+
- Active page highlighting with bold stroke
|
|
703
|
+
- Text labels under each icon
|
|
704
|
+
- Settings link appended automatically
|
|
705
|
+
|
|
706
|
+
### UpgradeSheet
|
|
707
|
+
|
|
708
|
+
Drawer component for premium upgrade prompts. Controlled via ref.
|
|
709
|
+
|
|
710
|
+
```javascript
|
|
711
|
+
import { useRef } from 'react';
|
|
712
|
+
import UpgradeSheet from '@stevederico/skateboard-ui/UpgradeSheet';
|
|
713
|
+
import { showUpgradeSheet } from '@stevederico/skateboard-ui/Utilities';
|
|
714
|
+
|
|
715
|
+
function MyComponent() {
|
|
716
|
+
const upgradeRef = useRef();
|
|
717
|
+
|
|
718
|
+
return (
|
|
719
|
+
<>
|
|
720
|
+
<button onClick={() => showUpgradeSheet(upgradeRef)}>
|
|
721
|
+
Upgrade
|
|
722
|
+
</button>
|
|
723
|
+
<UpgradeSheet ref={upgradeRef} userEmail={user.email} />
|
|
724
|
+
</>
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
**Ref Methods:** `show()`, `open()`, `hide()`, `close()`, `toggle()`
|
|
730
|
+
|
|
731
|
+
**Props:**
|
|
732
|
+
|
|
733
|
+
| Prop | Type | Description |
|
|
734
|
+
|------|------|-------------|
|
|
735
|
+
| userEmail | string | User's email for Stripe checkout |
|
|
736
|
+
|
|
737
|
+
**Reads from constants:** `stripeProducts[0]` (title, price, features)
|
|
738
|
+
|
|
739
|
+
### TextView
|
|
740
|
+
|
|
741
|
+
Renders legal documents with placeholder replacement.
|
|
742
|
+
|
|
743
|
+
```javascript
|
|
744
|
+
import TextView from '@stevederico/skateboard-ui/TextView';
|
|
745
|
+
|
|
746
|
+
<TextView details={constants.termsOfService} />
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
**Props:**
|
|
750
|
+
|
|
751
|
+
| Prop | Type | Description |
|
|
752
|
+
|------|------|-------------|
|
|
753
|
+
| details | string | Text content with optional placeholders |
|
|
754
|
+
| className | string | Additional CSS classes |
|
|
755
|
+
|
|
756
|
+
**Placeholders:** `_COMPANY_` → companyName, `_WEBSITE_` → companyWebsite, `_EMAIL_` → companyEmail
|
|
757
|
+
|
|
758
|
+
### ErrorBoundary
|
|
759
|
+
|
|
760
|
+
Catches render errors, unhandled promise rejections, and global errors. Shows an error card with retry options.
|
|
761
|
+
|
|
762
|
+
```javascript
|
|
763
|
+
import ErrorBoundary from '@stevederico/skateboard-ui/ErrorBoundary';
|
|
764
|
+
|
|
765
|
+
<ErrorBoundary>
|
|
766
|
+
<App />
|
|
767
|
+
</ErrorBoundary>
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
## Context (State Management)
|
|
771
|
+
|
|
772
|
+
```javascript
|
|
773
|
+
import { getState, useUser, useDispatch } from '@stevederico/skateboard-ui/Context';
|
|
774
|
+
|
|
775
|
+
function MyComponent() {
|
|
776
|
+
const { state, dispatch } = getState();
|
|
777
|
+
|
|
778
|
+
// Access state
|
|
779
|
+
const user = state.user;
|
|
780
|
+
const constants = state.constants;
|
|
781
|
+
|
|
782
|
+
// Dispatch actions
|
|
783
|
+
dispatch({ type: 'SET_USER', payload: userData });
|
|
784
|
+
dispatch({ type: 'CLEAR_USER' });
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### Optimized Hooks
|
|
789
|
+
|
|
790
|
+
Use these hooks to avoid unnecessary re-renders:
|
|
791
|
+
|
|
792
|
+
```javascript
|
|
793
|
+
import { useUser, useDispatch } from '@stevederico/skateboard-ui/Context';
|
|
794
|
+
|
|
795
|
+
// Only re-renders when user changes (not on sidebar/theme changes)
|
|
796
|
+
function ProfileCard() {
|
|
797
|
+
const user = useUser();
|
|
798
|
+
if (!user) return null;
|
|
799
|
+
return <div>{user.name}</div>;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// Stable dispatch reference, never causes re-renders
|
|
803
|
+
function SignOutButton() {
|
|
804
|
+
const dispatch = useDispatch();
|
|
805
|
+
return <button onClick={() => dispatch({ type: 'CLEAR_USER' })}>Sign Out</button>;
|
|
806
|
+
}
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
| Hook | Returns | Re-renders on |
|
|
810
|
+
|------|---------|---------------|
|
|
811
|
+
| `getState()` | `{ state, dispatch }` | Any state change |
|
|
812
|
+
| `useUser()` | `user` or `null` | User changes only |
|
|
813
|
+
| `useDispatch()` | `dispatch` | Never (stable) |
|
|
814
|
+
|
|
815
|
+
### State Shape
|
|
816
|
+
|
|
817
|
+
```javascript
|
|
818
|
+
{
|
|
819
|
+
user: {
|
|
820
|
+
id: string,
|
|
821
|
+
email: string,
|
|
822
|
+
name: string,
|
|
823
|
+
subscription: {
|
|
824
|
+
status: 'active' | 'canceled' | null,
|
|
825
|
+
expires: number, // Unix timestamp (seconds)
|
|
826
|
+
stripeID: string
|
|
827
|
+
}
|
|
828
|
+
} | null,
|
|
829
|
+
|
|
830
|
+
ui: {
|
|
831
|
+
sidebarVisible: boolean,
|
|
832
|
+
tabBarVisible: boolean
|
|
833
|
+
},
|
|
834
|
+
|
|
835
|
+
authOverlay: {
|
|
836
|
+
visible: boolean,
|
|
837
|
+
pendingCallback: Function | null
|
|
838
|
+
},
|
|
839
|
+
|
|
840
|
+
constants: Object // App configuration
|
|
841
|
+
}
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
### Available Actions
|
|
845
|
+
|
|
846
|
+
| Action | Payload | Description |
|
|
847
|
+
|--------|---------|-------------|
|
|
848
|
+
| `SET_USER` | user object | Set authenticated user |
|
|
849
|
+
| `CLEAR_USER` | — | Clear user (logout) |
|
|
850
|
+
| `SET_SIDEBAR_VISIBLE` | boolean | Show/hide sidebar |
|
|
851
|
+
| `SET_TABBAR_VISIBLE` | boolean | Show/hide tab bar |
|
|
852
|
+
| `SET_UI_VISIBILITY` | `{ sidebar?, tabBar? }` | Batch update UI visibility |
|
|
853
|
+
| `SHOW_AUTH_OVERLAY` | callback or null | Show auth dialog, optionally queue callback |
|
|
854
|
+
| `HIDE_AUTH_OVERLAY` | — | Hide auth dialog |
|
|
855
|
+
| `AUTH_OVERLAY_SUCCESS` | — | Auth success, run pending callback and close |
|
|
856
|
+
|
|
857
|
+
### localStorage Keys
|
|
858
|
+
|
|
859
|
+
All keys are namespaced with `{appName}_`:
|
|
860
|
+
|
|
861
|
+
| Key | Description |
|
|
862
|
+
|-----|-------------|
|
|
863
|
+
| `{appName}_user` | Persisted user object |
|
|
864
|
+
| `{appName}_csrf` | CSRF token (fallback, primary is cookie) |
|
|
865
|
+
| `{appName}_beforeCheckoutURL` | Redirect URL after Stripe checkout |
|
|
866
|
+
| `{appName}_beforeManageURL` | Redirect URL after Stripe portal |
|
|
867
|
+
|
|
868
|
+
## Utilities
|
|
869
|
+
|
|
870
|
+
```javascript
|
|
871
|
+
import {
|
|
872
|
+
apiRequest,
|
|
873
|
+
apiRequestWithParams,
|
|
874
|
+
isAuthenticated,
|
|
875
|
+
getCurrentUser,
|
|
876
|
+
isSubscriber,
|
|
877
|
+
getCSRFToken,
|
|
878
|
+
getBackendURL,
|
|
879
|
+
getAppKey,
|
|
880
|
+
getConstants,
|
|
881
|
+
getRemainingUsage,
|
|
882
|
+
trackUsage,
|
|
883
|
+
showCheckout,
|
|
884
|
+
showManage,
|
|
885
|
+
showUpgradeSheet,
|
|
886
|
+
showSidebar,
|
|
887
|
+
hideSidebar,
|
|
888
|
+
showTabBar,
|
|
889
|
+
hideTabBar,
|
|
890
|
+
setSidebarVisible,
|
|
891
|
+
setTabBarVisible,
|
|
892
|
+
setUIVisibility,
|
|
893
|
+
timestampToString,
|
|
894
|
+
useListData,
|
|
895
|
+
useForm,
|
|
896
|
+
useAppSetup,
|
|
897
|
+
isAppMode,
|
|
898
|
+
validateConstants,
|
|
899
|
+
} from '@stevederico/skateboard-ui/Utilities';
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
### API Requests
|
|
903
|
+
|
|
904
|
+
```javascript
|
|
905
|
+
// GET
|
|
906
|
+
const data = await apiRequest('/deals');
|
|
907
|
+
|
|
908
|
+
// POST
|
|
909
|
+
const newDeal = await apiRequest('/deals', {
|
|
910
|
+
method: 'POST',
|
|
911
|
+
body: JSON.stringify({ name: 'New Deal', amount: 5000 })
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// GET with query params
|
|
915
|
+
const filtered = await apiRequestWithParams('/deals', { status: 'active', limit: 10 });
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
**Features:**
|
|
919
|
+
- Auto-includes credentials (cookies)
|
|
920
|
+
- Auto-adds `X-CSRF-Token` header for POST, PUT, DELETE, PATCH
|
|
921
|
+
- Auto-redirects to `/signout` on 401 (unless authOverlay mode)
|
|
922
|
+
- Auto-retries once on CSRF 403 failure
|
|
923
|
+
|
|
924
|
+
### Auth Utilities
|
|
925
|
+
|
|
926
|
+
```javascript
|
|
927
|
+
// Client-side check (fast, no network)
|
|
928
|
+
if (isAuthenticated()) {
|
|
929
|
+
const user = getCurrentUser();
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Server-side validation
|
|
933
|
+
const user = await getCurrentUser(); // Calls GET /me
|
|
934
|
+
|
|
935
|
+
// Check subscription
|
|
936
|
+
const subscribed = await isSubscriber(); // Calls GET /isSubscriber
|
|
937
|
+
|
|
938
|
+
// Get CSRF token (from cookie, falls back to localStorage)
|
|
939
|
+
const token = getCSRFToken();
|
|
940
|
+
|
|
941
|
+
// Get backend URL (devBackendURL in dev, backendURL in production)
|
|
942
|
+
const url = getBackendURL();
|
|
943
|
+
|
|
944
|
+
// Generate app-namespaced localStorage key
|
|
945
|
+
const key = getAppKey('user'); // → "{appName}_user"
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
### Usage Tracking
|
|
949
|
+
|
|
950
|
+
```javascript
|
|
951
|
+
// Check remaining usage for an action
|
|
952
|
+
const usage = await getRemainingUsage('messages');
|
|
953
|
+
// { remaining: 15, total: 20, isSubscriber: false }
|
|
954
|
+
|
|
955
|
+
// Track usage (decrements remaining)
|
|
956
|
+
const updated = await trackUsage('messages');
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
### Stripe Payments
|
|
960
|
+
|
|
961
|
+
```javascript
|
|
962
|
+
// Redirect to Stripe checkout
|
|
963
|
+
showCheckout('user@example.com', 0); // productIndex defaults to 0
|
|
964
|
+
|
|
965
|
+
// Open Stripe billing portal
|
|
966
|
+
showManage('cus_abc123');
|
|
967
|
+
|
|
968
|
+
// Show upgrade sheet if not subscriber
|
|
969
|
+
showUpgradeSheet(upgradeSheetRef);
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Data Fetching Hook
|
|
973
|
+
|
|
974
|
+
```javascript
|
|
975
|
+
import { useListData } from '@stevederico/skateboard-ui/Utilities';
|
|
976
|
+
|
|
977
|
+
function DealsList() {
|
|
978
|
+
const { data, loading, error, refetch } = useListData('/deals');
|
|
979
|
+
|
|
980
|
+
if (loading) return <div>Loading...</div>;
|
|
981
|
+
if (error) return <div>Error: {error}</div>;
|
|
982
|
+
|
|
983
|
+
return data.map(deal => <DealCard key={deal.id} {...deal} />);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// With custom sort
|
|
987
|
+
const { data } = useListData('/deals', (a, b) => b.amount - a.amount);
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
### Form Hook
|
|
991
|
+
|
|
992
|
+
```javascript
|
|
993
|
+
import { useForm } from '@stevederico/skateboard-ui/Utilities';
|
|
994
|
+
|
|
995
|
+
function ContactForm() {
|
|
996
|
+
const { values, handleChange, handleSubmit, reset, submitting, error } = useForm(
|
|
997
|
+
{ name: '', email: '', message: '' },
|
|
998
|
+
async (formValues) => {
|
|
999
|
+
await apiRequest('/contact', {
|
|
1000
|
+
method: 'POST',
|
|
1001
|
+
body: JSON.stringify(formValues)
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
1005
|
+
|
|
1006
|
+
return (
|
|
1007
|
+
<form onSubmit={handleSubmit}>
|
|
1008
|
+
<input name="name" value={values.name} onChange={handleChange} />
|
|
1009
|
+
<input name="email" value={values.email} onChange={handleChange} />
|
|
1010
|
+
<textarea name="message" value={values.message} onChange={handleChange} />
|
|
1011
|
+
<button type="submit" disabled={submitting}>Send</button>
|
|
1012
|
+
{error && <p>{error}</p>}
|
|
1013
|
+
</form>
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
### Timestamp Formatting
|
|
1019
|
+
|
|
1020
|
+
```javascript
|
|
1021
|
+
import { timestampToString } from '@stevederico/skateboard-ui/Utilities';
|
|
1022
|
+
|
|
1023
|
+
timestampToString(1706000000, 'ago'); // "2 hours ago"
|
|
1024
|
+
timestampToString(1706000000, 'DOB'); // "Jan 23, 2024"
|
|
1025
|
+
timestampToString(1706000000, 'DOBT'); // "Jan 23, 2024 3:00 PM"
|
|
1026
|
+
timestampToString(1706000000, 'ISO'); // "2024-01-23"
|
|
1027
|
+
timestampToString(1706000000, 'day-month-time');// "23 Jan 3:00 PM"
|
|
1028
|
+
timestampToString(1706000000, 'day'); // "Monday"
|
|
1029
|
+
timestampToString(1706000000, 'time'); // "3:00 PM"
|
|
1030
|
+
timestampToString(1706000000, 'full'); // "Monday, Jan 23, 2024 3:00 PM"
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### UI Visibility Control
|
|
1034
|
+
|
|
1035
|
+
```javascript
|
|
1036
|
+
// Programmatic control
|
|
1037
|
+
hideSidebar();
|
|
1038
|
+
showSidebar();
|
|
1039
|
+
hideTabBar();
|
|
1040
|
+
showTabBar();
|
|
1041
|
+
|
|
1042
|
+
// Set directly
|
|
1043
|
+
setSidebarVisible(false);
|
|
1044
|
+
setTabBarVisible(true);
|
|
1045
|
+
|
|
1046
|
+
// Batch control
|
|
1047
|
+
setUIVisibility({ sidebar: false, tabBar: false });
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
### Other Utilities
|
|
1051
|
+
|
|
1052
|
+
```javascript
|
|
1053
|
+
// Check if running inside native WebKit wrapper (iOS/macOS app)
|
|
1054
|
+
if (isAppMode()) { /* native context */ }
|
|
1055
|
+
|
|
1056
|
+
// Validate constants object (called internally by createSkateboardApp)
|
|
1057
|
+
validateConstants(constants);
|
|
1058
|
+
|
|
1059
|
+
// Get constants object
|
|
1060
|
+
const constants = getConstants();
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
## Lazy Authentication (Auth Overlay)
|
|
1064
|
+
|
|
1065
|
+
Let users explore `/app` without signing in — prompt them only when they perform a protected action.
|
|
1066
|
+
|
|
1067
|
+
### Setup
|
|
1068
|
+
|
|
1069
|
+
Set `authOverlay: true` in your constants to allow unauthenticated access to `/app` routes:
|
|
1070
|
+
|
|
1071
|
+
```json
|
|
1072
|
+
{
|
|
1073
|
+
"authOverlay": true
|
|
1074
|
+
}
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
The `AuthOverlay` component is rendered automatically by `createSkateboardApp` — no additional wiring needed.
|
|
1078
|
+
|
|
1079
|
+
### Usage
|
|
1080
|
+
|
|
1081
|
+
```javascript
|
|
1082
|
+
import { useAuthGate } from '@stevederico/skateboard-ui/useAuthGate';
|
|
1083
|
+
|
|
1084
|
+
function SaveButton() {
|
|
1085
|
+
const requireAuth = useAuthGate();
|
|
1086
|
+
|
|
1087
|
+
function handleSave() {
|
|
1088
|
+
requireAuth(() => {
|
|
1089
|
+
// Only runs if user is authenticated
|
|
1090
|
+
// If not signed in, auth overlay appears first
|
|
1091
|
+
saveThing();
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
return <button onClick={handleSave}>Save</button>;
|
|
1096
|
+
}
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
### How It Works
|
|
1100
|
+
|
|
1101
|
+
1. User clicks a protected action (Save, Like, Post, etc.)
|
|
1102
|
+
2. `requireAuth()` checks if user is signed in
|
|
1103
|
+
3. If signed in — callback runs immediately
|
|
1104
|
+
4. If not — a modal dialog appears with sign-in/sign-up forms
|
|
1105
|
+
5. After successful auth, the original callback executes automatically
|
|
1106
|
+
6. User stays on the same page throughout — no navigation
|
|
1107
|
+
|
|
1108
|
+
The dialog supports toggling between sign-in and sign-up modes inline, and can be dismissed with the X button (cancels the action).
|
|
1109
|
+
|
|
1110
|
+
## Toast Notifications
|
|
1111
|
+
|
|
1112
|
+
Toasts are provided by [Sonner](https://sonner.emilkowal.dev/) and rendered automatically by `createSkateboardApp`.
|
|
1113
|
+
|
|
1114
|
+
```javascript
|
|
1115
|
+
import { toast } from 'sonner';
|
|
1116
|
+
|
|
1117
|
+
toast.success('Changes saved!');
|
|
1118
|
+
toast.error('Failed to save');
|
|
1119
|
+
toast.loading('Saving...');
|
|
1120
|
+
toast.info('New feature available');
|
|
1121
|
+
toast.warning('This action cannot be undone');
|
|
1122
|
+
|
|
1123
|
+
// Promise-based
|
|
1124
|
+
toast.promise(
|
|
1125
|
+
fetch('/api/data'),
|
|
1126
|
+
{
|
|
1127
|
+
loading: 'Loading...',
|
|
1128
|
+
success: 'Data loaded!',
|
|
1129
|
+
error: 'Failed to load'
|
|
1130
|
+
}
|
|
1131
|
+
);
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
## Styling
|
|
1135
|
+
|
|
1136
|
+
Import base theme and override as needed:
|
|
1137
|
+
|
|
1138
|
+
```css
|
|
1139
|
+
/* styles.css */
|
|
1140
|
+
@import "@stevederico/skateboard-ui/styles.css";
|
|
1141
|
+
|
|
1142
|
+
@source '../../node_modules/@stevederico/skateboard-ui';
|
|
1143
|
+
|
|
1144
|
+
@theme {
|
|
1145
|
+
--color-app: var(--color-purple-500);
|
|
1146
|
+
}
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
### Theme Variables
|
|
1150
|
+
|
|
1151
|
+
| Variable | Description |
|
|
1152
|
+
|----------|-------------|
|
|
1153
|
+
| `--color-app` | Primary brand color (used for app icon backgrounds, gradient buttons) |
|
|
1154
|
+
| `--background` | Page background |
|
|
1155
|
+
| `--foreground` | Text color |
|
|
1156
|
+
| `--accent` | Secondary backgrounds |
|
|
1157
|
+
| `--radius` | Border radius |
|
|
1158
|
+
|
|
1159
|
+
Dark mode is automatic via CSS custom properties and `next-themes`.
|
|
1160
|
+
|
|
1161
|
+
## shadcn/ui Components
|
|
1162
|
+
|
|
1163
|
+
51 components available at `@stevederico/skateboard-ui/shadcn/ui/*`:
|
|
1164
|
+
|
|
1165
|
+
```javascript
|
|
1166
|
+
import { Button } from '@stevederico/skateboard-ui/shadcn/ui/button';
|
|
1167
|
+
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction } from '@stevederico/skateboard-ui/shadcn/ui/card';
|
|
1168
|
+
import { Input } from '@stevederico/skateboard-ui/shadcn/ui/input';
|
|
1169
|
+
import { Label } from '@stevederico/skateboard-ui/shadcn/ui/label';
|
|
1170
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@stevederico/skateboard-ui/shadcn/ui/dialog';
|
|
1171
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@stevederico/skateboard-ui/shadcn/ui/avatar';
|
|
1172
|
+
import { Badge } from '@stevederico/skateboard-ui/shadcn/ui/badge';
|
|
1173
|
+
import { Separator } from '@stevederico/skateboard-ui/shadcn/ui/separator';
|
|
1174
|
+
import { ScrollArea } from '@stevederico/skateboard-ui/shadcn/ui/scroll-area';
|
|
1175
|
+
import { Skeleton } from '@stevederico/skateboard-ui/shadcn/ui/skeleton';
|
|
1176
|
+
import { Alert, AlertDescription, AlertTitle } from '@stevederico/skateboard-ui/shadcn/ui/alert';
|
|
1177
|
+
import { Progress } from '@stevederico/skateboard-ui/shadcn/ui/progress';
|
|
1178
|
+
import { Switch } from '@stevederico/skateboard-ui/shadcn/ui/switch';
|
|
1179
|
+
import { Checkbox } from '@stevederico/skateboard-ui/shadcn/ui/checkbox';
|
|
1180
|
+
import { Textarea } from '@stevederico/skateboard-ui/shadcn/ui/textarea';
|
|
1181
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@stevederico/skateboard-ui/shadcn/ui/tooltip';
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
```javascript
|
|
1185
|
+
import {
|
|
1186
|
+
Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
|
|
1187
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/select';
|
|
1188
|
+
|
|
1189
|
+
import {
|
|
1190
|
+
DropdownMenu, DropdownMenuContent, DropdownMenuItem,
|
|
1191
|
+
DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger,
|
|
1192
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/dropdown-menu';
|
|
1193
|
+
|
|
1194
|
+
import {
|
|
1195
|
+
AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
|
|
1196
|
+
AlertDialogDescription, AlertDialogFooter, AlertDialogHeader,
|
|
1197
|
+
AlertDialogTitle, AlertDialogTrigger,
|
|
1198
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/alert-dialog';
|
|
1199
|
+
|
|
1200
|
+
import {
|
|
1201
|
+
Accordion, AccordionContent, AccordionItem, AccordionTrigger,
|
|
1202
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/accordion';
|
|
1203
|
+
|
|
1204
|
+
import {
|
|
1205
|
+
Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
|
|
1206
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/table';
|
|
1207
|
+
|
|
1208
|
+
import {
|
|
1209
|
+
Tabs, TabsContent, TabsList, TabsTrigger,
|
|
1210
|
+
} from '@stevederico/skateboard-ui/shadcn/ui/tabs';
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
### Utilities
|
|
1214
|
+
|
|
1215
|
+
```javascript
|
|
1216
|
+
// Tailwind className merger
|
|
1217
|
+
import { cn } from '@stevederico/skateboard-ui/shadcn/lib/utils';
|
|
1218
|
+
|
|
1219
|
+
cn('px-2 py-1', condition && 'bg-red-500', 'px-4'); // Merges without conflicts
|
|
1220
|
+
|
|
1221
|
+
// Mobile detection hook (< 768px)
|
|
1222
|
+
import { useIsMobile } from '@stevederico/skateboard-ui/shadcn/hooks/use-mobile';
|
|
1223
|
+
|
|
1224
|
+
const isMobile = useIsMobile();
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
All components support dark mode automatically and accept a `className` prop for customization.
|
|
1228
|
+
|
|
1229
|
+
## Dependencies
|
|
1230
|
+
|
|
1231
|
+
### Peer Dependencies
|
|
1232
|
+
- React 19.1+
|
|
1233
|
+
- react-dom 19.1+
|
|
1234
|
+
- react-router-dom 7.0+
|
|
1235
|
+
|
|
1236
|
+
### Core Dependencies
|
|
1237
|
+
- @base-ui/react — Accessible UI primitives
|
|
1238
|
+
- lucide-react — Icon library
|
|
1239
|
+
- next-themes — Theme management
|
|
1240
|
+
- class-variance-authority — Variant styling
|
|
1241
|
+
- clsx & tailwind-merge — className utilities
|
|
1242
|
+
- sonner — Toast notifications
|
|
1243
|
+
- vaul — Drawer primitives
|
|
1244
|
+
- cmdk — Command menu
|
|
1245
|
+
- embla-carousel-react — Carousel
|
|
1246
|
+
- react-day-picker — Calendar
|
|
1247
|
+
- react-resizable-panels — Resizable panels
|
|
1248
|
+
- recharts — Charts
|
|
1249
|
+
|
|
1250
|
+
## Repository
|
|
1251
|
+
|
|
1252
|
+
https://github.com/stevederico/skateboard-ui
|