@gnome-ui/react-native 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,9 +14,12 @@ React Native component library following the [GNOME Human Interface Guidelines](
14
14
  > `Link`, `TextField`, `Switch`, `Checkbox`, `RadioButton`), Tier 2 Layout &
15
15
  > Containers (`Separator`, `Card`, `BoxedList`, `ActionRow`, `HeaderBar`),
16
16
  > and Tier 3 Navigation (`Tabs`, `ViewSwitcher`, `Sidebar`, `SearchBar`,
17
- > `PathBar`) fully ported. Tier 4 Feedback in progress: `Spinner`,
18
- > `ProgressBar`, `Skeleton`, `Toast`/`Toaster`, `Banner`, and `Dialog`
19
- > shipped `Tooltip`, `Status Page`, and `AnimatedIcon` remain. Component
17
+ > `PathBar`) fully ported. Tier 4 Feedback: `Spinner`, `ProgressBar`,
18
+ > `Skeleton`, `Toast`/`Toaster`, `Banner`, `Dialog`, `Tooltip`, and
19
+ > `AnimatedIcon` (which brought a new `Icon` component along with it, as its
20
+ > own public component) shipped — `Status Page` skipped for now. Tier 5
21
+ > Advanced Controls in progress: `Dropdown` shipped — `Slider`,
22
+ > `Spin Button`, `Avatar`, `Badge`, and `Popover` remain. Component
20
23
  > ports from `@gnome-ui/react` continue tier by tier. See
21
24
  > [ROADMAP.md](../../ROADMAP.md) Priority 3.
22
25
 
@@ -790,12 +793,147 @@ consistency with the established pattern, but this is the component where
790
793
  that tradeoff matters most — worth prioritizing for real-device screen
791
794
  reader verification before it's treated as settled.
792
795
 
796
+ ### Tooltip
797
+
798
+ ```tsx
799
+ import { Button, Tooltip } from '@gnome-ui/react-native';
800
+
801
+ <Tooltip label="Save file" placement="top">
802
+ <Button accessibilityLabel="Save">Save</Button>
803
+ </Tooltip>;
804
+ ```
805
+
806
+ Floating informational label. Positioned automatically and flips to the
807
+ opposite side (then to whichever side actually fits) when the preferred
808
+ placement has no room — the same algorithm as `@gnome-ui/react`'s
809
+ `Tooltip`, measured with `measureInWindow()` instead of
810
+ `getBoundingClientRect()`.
811
+
812
+ **Trigger differs from the web version by necessity**: the web `Tooltip`
813
+ only shows on mouse hover / keyboard focus — touch has no hover state, so
814
+ it explicitly never shows on touch. RN is touch-first, so the primary
815
+ trigger here is **long-press** (`delayLongPress={delay}`, released via
816
+ `onPressOut`) — the standard mobile "peek" idiom. `onHoverIn`/`onHoverOut`
817
+ are also wired for hover-capable input (trackpad/mouse on iPad, or a
818
+ pointer-driven RN target) and `onFocus`/`onBlur` for external-keyboard
819
+ accessibility, both delayed the same way the web version delays hover.
820
+
821
+ Built on RN's own `Modal` (transparent, `pointerEvents="box-none"`), the
822
+ same portal-substitute `Dialog` uses. `role="tooltip"` ports 1:1 — RN's
823
+ `Role` union already has a `"tooltip"` value. `aria-describedby` has no RN
824
+ equivalent, so the label is set as the trigger's `accessibilityHint`
825
+ instead (unless the trigger already provides its own). The bubble's arrow
826
+ reuses the same zero-size / transparent-border-on-three-sides triangle
827
+ trick as the web CSS — RN `View`s support per-side `border*Color` too, the
828
+ same technique `Spinner`'s ring already relies on.
829
+
830
+ Not ported: repositioning on scroll/resize while visible (RN has no global
831
+ scroll event, and a long-press is naturally cancelled by a scroll gesture
832
+ starting). `tooltipBgColor`/`tooltipFgColor` aren't real `@gnome-ui/core`
833
+ tokens (only CSS var fallbacks), so the RN port hardcodes the same literal
834
+ light/dark values, the same workaround `Spinner`'s track color established.
835
+
836
+ ### Icon
837
+
838
+ ```tsx
839
+ import { Search } from '@gnome-ui/icons';
840
+ import { Icon } from '@gnome-ui/react-native';
841
+
842
+ <Icon icon={Search} label="Search" size="lg" color="blue" />;
843
+ ```
844
+
845
+ Renders an icon as an inline SVG via `react-native-svg` (a new peer
846
+ dependency — this package's first). Accepts the same `AnyIconDefinition`
847
+ union as `@gnome-ui/react`'s `Icon`: a structured `paths`-based
848
+ `IconDefinition` from `@gnome-ui/icons`, a `simple-icons` `SimpleIcon`, or a
849
+ plain `{ path }` object. `color` picks a named GNOME palette hue
850
+ (`theme.blue3`, `theme.red3`, …) — RN has no `currentColor` to inherit from
851
+ a parent the way the web version does, so omitting `color` resolves to the
852
+ theme's default foreground color explicitly instead.
853
+
854
+ `animated` icons (`Syncing`, `Recording`, `Downloading`, `Connecting`) carry
855
+ raw `svg` markup instead of `paths` — rendered here through `react-native-
856
+ svg`'s `SvgXml`. It parses the structural elements (`<g>`/`<path>`/
857
+ `<circle>`) but has no CSS engine, so the markup's embedded `<style>`/
858
+ `@keyframes` block is silently dropped and the shapes render at their
859
+ authored rest position — which happens to be exactly the desired inert,
860
+ static-frame behavior for a plain `<Icon>`, no special-casing needed. Wrap
861
+ in `<AnimatedIcon>` to actually play the motion.
862
+
863
+ ### AnimatedIcon
864
+
865
+ ```tsx
866
+ import { Syncing } from '@gnome-ui/icons';
867
+ import { AnimatedIcon } from '@gnome-ui/react-native';
868
+
869
+ <AnimatedIcon icon={Syncing} playing={isSyncing} label="Syncing" />;
870
+ ```
871
+
872
+ Plays the motion for a known `animated` icon (`Syncing`, `Recording`,
873
+ `Downloading`, `Connecting`) — rendered through plain `<Icon>`, these show a
874
+ static frame instead, same as `@gnome-ui/react`'s `AnimatedIcon`.
875
+
876
+ Unlike the web version (which plays a CSS animation embedded in the icon's
877
+ raw `svg` markup via a `--gnome-icon-play-state` custom property), RN has
878
+ no CSS engine to interpret `@keyframes` at all. Each of the 4 known icons'
879
+ motion is instead hand-built with `Animated`, matched by referential
880
+ identity against `@gnome-ui/icons`' own exports (`Syncing` → full-turn
881
+ rotation, `Recording` → opacity pulse, `Downloading` → a translate+opacity
882
+ "drop" on the arrow over a static tray, `Connecting` → three signal dots
883
+ pulsing in a staggered sweep) — an icon `AnimatedIcon` doesn't recognize
884
+ (a future 5th animated icon, or a consumer-authored one) falls back to the
885
+ static `<Icon>` frame rather than throwing. Regardless of `playing`, the
886
+ animation is always paused when the OS reduced-motion setting is on.
887
+
888
+ ### Dropdown
889
+
890
+ ```tsx
891
+ import { Dropdown } from '@gnome-ui/react-native';
892
+
893
+ <Dropdown
894
+ options={[
895
+ { value: 'blue', label: 'Blue' },
896
+ { value: 'green', label: 'Green', description: 'A calm accent' },
897
+ ]}
898
+ value={accentColor}
899
+ onChange={setAccentColor}
900
+ placeholder="Accent color"
901
+ />;
902
+ ```
903
+
904
+ Expandable option list following the Adwaita combo-row pattern, mirroring
905
+ `@gnome-ui/react`'s `Dropdown`.
906
+
907
+ Built on RN's own `Modal` (transparent) — the same portal-substitute
908
+ `Dialog`/`Tooltip` already use — with a full-screen backdrop `Pressable`
909
+ that closes the list on an outside tap (the RN analog of the web version's
910
+ document-level "click outside" listener; unlike `Tooltip`'s backdrop, this
911
+ one isn't `pointerEvents="box-none"`, since it's meant to catch that tap
912
+ rather than pass it through). `open` flips synchronously on trigger press;
913
+ the trigger's on-screen rect and the panel's own rendered height each
914
+ resolve independently into state, combined by a separate effect into the
915
+ final position and flip-up/flip-down direction — the same two-independent-
916
+ async-measurements pattern `Tooltip` established.
917
+
918
+ Keyboard navigation (↑/↓ roving highlight, Home/End, type-ahead) has no
919
+ port — RN's touch-first model has no keyboard focus to drive it, the same
920
+ reasoning that already dropped `TabBar`'s roving-tabindex arrow keys.
921
+ Selection is by direct tap only. `role="combobox"` on the trigger ports
922
+ 1:1; RN's `Role` union has no `"listbox"` value, so the panel uses
923
+ `role="list"` instead — the same closest-available substitution `BoxedList`
924
+ already established for a plain list container.
925
+
793
926
  ## Installation
794
927
 
795
928
  ```bash
796
- npm install @gnome-ui/react-native react-native
929
+ npm install @gnome-ui/react-native react-native react-native-svg
797
930
  ```
798
931
 
932
+ `react-native-svg` is a peer dependency, only needed for `Icon`/
933
+ `AnimatedIcon` — it ships as one of Expo Go's included native modules, so
934
+ Expo projects on `npx expo install react-native-svg` need no extra native
935
+ build step; bare RN projects need it linked as usual for a native module.
936
+
799
937
  ## Example app
800
938
 
801
939
  [`apps/react-native-example`](../../apps/react-native-example) is a
@@ -0,0 +1,38 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ import { IconProps } from '../Icon';
3
+ export interface AnimatedIconProps extends Omit<IconProps, 'icon'> {
4
+ /** Animated icon from `@gnome-ui/icons` (`animated: true` — `Syncing`, `Recording`, `Downloading`, `Connecting`). */
5
+ icon: IconDefinition;
6
+ /**
7
+ * Whether the animation plays. Defaults to `true`.
8
+ *
9
+ * Regardless of this prop, the animation is always paused when the OS
10
+ * reduced-motion setting is on — callers don't need to check
11
+ * `useReducedMotion()` themselves.
12
+ */
13
+ playing?: boolean;
14
+ }
15
+ /**
16
+ * Plays the motion for a known `animated` icon from `@gnome-ui/icons`
17
+ * (`Syncing`, `Recording`, `Downloading`, `Connecting`) — rendered through
18
+ * plain `<Icon>`, these show a static frame instead.
19
+ *
20
+ * Unlike `@gnome-ui/react`'s `AnimatedIcon` (which plays a CSS animation
21
+ * embedded in the icon's raw `svg` markup via a `--gnome-icon-play-state`
22
+ * custom property), RN has no CSS engine to interpret `@keyframes` at all —
23
+ * `<Icon>` already drops the `<style>` block silently (see its own doc
24
+ * comment), and this component instead hand-builds each of the 4 known
25
+ * icons' exact motion with `Animated`, matched against `RECIPES` by
26
+ * reference. When playing and reduced motion is off, it renders its own
27
+ * `<Svg>` with the matching `*Motion` recipe as children; otherwise (not
28
+ * playing, reduced motion on, or an icon `RECIPES` doesn't recognize) it
29
+ * defers straight to `<Icon>`.
30
+ *
31
+ * Useful for progress, sync, recording, download, and connection states, or
32
+ * cross-fading between icons by swapping `icon` while `playing` stays true.
33
+ *
34
+ * @example
35
+ * import { Syncing } from "@gnome-ui/icons";
36
+ * <AnimatedIcon icon={Syncing} playing={isSyncing} label="Syncing" />
37
+ */
38
+ export declare const AnimatedIcon: ({ icon, playing, size, width, height, label, color, }: AnimatedIconProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { AnimatedIconProps } from './AnimatedIcon';
2
+ export { AnimatedIcon } from './AnimatedIcon';
@@ -0,0 +1,56 @@
1
+ import { StyleProp, ViewStyle } from 'react-native';
2
+ export interface DropdownOption<V extends string = string> {
3
+ /** The value submitted / returned on selection. */
4
+ value: V;
5
+ /** Display label shown in the list and trigger. */
6
+ label: string;
7
+ /** Optional descriptive text shown below the label. */
8
+ description?: string;
9
+ /** Whether the option is selectable. */
10
+ disabled?: boolean;
11
+ }
12
+ export interface DropdownProps<V extends string = string> {
13
+ /** The list of selectable options. */
14
+ options: DropdownOption<V>[];
15
+ /** The currently selected value. */
16
+ value?: V;
17
+ /** Called when the user selects an option. */
18
+ onChange?: (value: V) => void;
19
+ /** Placeholder shown when no option is selected. */
20
+ placeholder?: string;
21
+ /** Accessible label for the control. */
22
+ accessibilityLabel?: string;
23
+ /** Disables the entire control. */
24
+ disabled?: boolean;
25
+ style?: StyleProp<ViewStyle>;
26
+ testID?: string;
27
+ }
28
+ /**
29
+ * Expandable option list following the Adwaita combo-row / drop-down
30
+ * pattern, mirroring `@gnome-ui/react`'s `Dropdown`.
31
+ *
32
+ * Built on RN's own `Modal` (transparent) — the same portal-substitute
33
+ * `Dialog`/`Tooltip` already use — with a full-screen backdrop `Pressable`
34
+ * (not `pointerEvents="box-none"` like `Tooltip`'s: unlike a tooltip, this
35
+ * panel is meant to catch and close on an outside tap, the RN analog of the
36
+ * web version's document-level "click outside" listener). `open` flips
37
+ * synchronously on trigger press; the trigger's on-screen rect
38
+ * (`measureInWindow`) and the panel's own rendered height (`onLayout`) each
39
+ * resolve independently into state, combined by a separate effect into the
40
+ * final `top`/`left`/`width`/`flipUp` — the same two-independent-
41
+ * async-measurements pattern `Tooltip` established (and for the same
42
+ * reason: gating `open` itself on the native measurement callback would
43
+ * make the component untestable in this package's Jest environment, where
44
+ * `measureInWindow` never calls back).
45
+ *
46
+ * Keyboard navigation (↑/↓ roving highlight, Home/End, type-ahead) has no
47
+ * port — RN's touch-first model has no keyboard focus to drive it, the
48
+ * same reasoning that already dropped `TabBar`'s roving-tabindex arrow
49
+ * keys. Selection is by direct tap only.
50
+ *
51
+ * `role="combobox"` on the trigger ports 1:1. RN's `Role` union has no
52
+ * `"listbox"` value (unlike `"option"`, which does exist) — the panel uses
53
+ * `role="list"` instead, the same closest-available substitution `BoxedList`
54
+ * already established for a plain list container.
55
+ */
56
+ export declare const Dropdown: <V extends string = string>({ options, value, onChange, placeholder, accessibilityLabel, disabled, style, testID, }: DropdownProps<V>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { DropdownOption, DropdownProps } from './Dropdown';
2
+ export { Dropdown } from './Dropdown';
@@ -0,0 +1,56 @@
1
+ import { AnyIconDefinition } from '@gnome-ui/icons';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export type IconSize = 'sm' | 'md' | 'lg';
4
+ /** Named GNOME palette color for the icon. `"default"` (or omitting the prop) resolves to the theme's default foreground color. */
5
+ export type IconColor = 'default' | 'blue' | 'green' | 'yellow' | 'orange' | 'red' | 'purple' | 'brown';
6
+ export interface IconProps {
7
+ /** Icon from `@gnome-ui/icons`, a `simple-icons` icon, or a raw `{ path }` object. */
8
+ icon: AnyIconDefinition;
9
+ /**
10
+ * Rendered size.
11
+ * - `sm` — 12 px
12
+ * - `md` — 16 px (default)
13
+ * - `lg` — 20 px
14
+ *
15
+ * Override with `width`/`height` for non-standard sizes.
16
+ */
17
+ size?: IconSize;
18
+ width?: number;
19
+ height?: number;
20
+ /** Accessible label. Omit for decorative icons — they are hidden from screen readers. */
21
+ label?: string;
22
+ /**
23
+ * Named GNOME palette color. Omit (or pass `"default"`) to use the
24
+ * theme's default foreground color — RN has no `currentColor`
25
+ * equivalent to inherit from a parent, unlike the web version.
26
+ */
27
+ color?: IconColor;
28
+ /** Forwarded to the underlying `Svg` — useful for a `transform` (e.g. a rotated disclosure chevron) or `margin`. */
29
+ style?: StyleProp<ViewStyle>;
30
+ }
31
+ /**
32
+ * Renders an icon as an inline SVG, via `react-native-svg`.
33
+ *
34
+ * Accepts icons from `@gnome-ui/icons`, any `simple-icons` icon, or a plain
35
+ * `{ path }` object — same `AnyIconDefinition` union as `@gnome-ui/react`'s
36
+ * `Icon`. Pass `label` only when the icon conveys meaning on its own.
37
+ *
38
+ * `animated` icons (`Syncing`, `Recording`, …) carry raw `svg` markup
39
+ * instead of `paths` — rendered here through `SvgXml`, which parses the
40
+ * structural elements (`<g>`/`<path>`/`<circle>`) but has no CSS engine, so
41
+ * the embedded `<style>`/`@keyframes` block is silently dropped and the
42
+ * shapes render at their authored rest position. That happens to be exactly
43
+ * the desired "inert, static frame" behavior for a plain `<Icon>` — no
44
+ * special-casing needed here; wrap in `<AnimatedIcon>` to actually play the
45
+ * motion (RN has to hand-build that with `Animated`, since there is no CSS
46
+ * animation engine to interpret the markup's keyframes).
47
+ *
48
+ * @example
49
+ * import { Search } from "@gnome-ui/icons";
50
+ * <Icon icon={Search} label="Search" />
51
+ *
52
+ * @example
53
+ * import { siGithub } from "simple-icons";
54
+ * <Icon icon={siGithub} label="GitHub" />
55
+ */
56
+ export declare const Icon: ({ icon, size, width, height, label, color, style }: IconProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { IconColor, IconProps, IconSize } from './Icon';
2
+ export { Icon } from './Icon';
@@ -0,0 +1,19 @@
1
+ import { useGnomeTheme } from '../../GnomeProvider';
2
+ import { IconColor, IconSize } from './Icon';
3
+ /**
4
+ * Non-component helpers shared between `Icon` and `AnimatedIcon` — kept in
5
+ * their own module (not exported from `Icon.tsx` itself) so both files stay
6
+ * component-only for Fast Refresh, per the project's `react-refresh/
7
+ * only-export-components` lint rule.
8
+ */
9
+ export declare const ICON_SIZE_MAP: Record<IconSize, number>;
10
+ export declare function resolveIconColor(theme: ReturnType<typeof useGnomeTheme>, color: IconColor | undefined): string;
11
+ export declare function iconAccessibilityProps(label: string | undefined): {
12
+ accessible: true;
13
+ accessibilityLabel: string;
14
+ accessibilityRole: "image";
15
+ } | {
16
+ accessible: false;
17
+ accessibilityRole: "none";
18
+ accessibilityLabel?: undefined;
19
+ };
@@ -0,0 +1,88 @@
1
+ import { ReactElement, Ref } from 'react';
2
+ import { PressableProps, View } from 'react-native';
3
+ export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
4
+ export interface TooltipProps {
5
+ /**
6
+ * The tooltip label. Keep it short — a noun phrase or brief description.
7
+ * Do not duplicate information already visible on screen.
8
+ */
9
+ label: string;
10
+ /**
11
+ * Preferred placement relative to the trigger.
12
+ * The tooltip flips automatically if there is not enough space.
13
+ * Defaults to `"top"`.
14
+ */
15
+ placement?: TooltipPlacement;
16
+ /**
17
+ * Delay in milliseconds before the tooltip appears, on both the
18
+ * long-press and hover/focus triggers. Defaults to `500`. Set to `0` for
19
+ * instant.
20
+ */
21
+ delay?: number;
22
+ /**
23
+ * The element that triggers the tooltip.
24
+ * Must be a single element built on `Pressable` (e.g. `Button`, `Card`)
25
+ * that forwards its `ref` to the underlying `View`.
26
+ */
27
+ children: ReactElement<PressableProps & {
28
+ ref?: Ref<View>;
29
+ }>;
30
+ }
31
+ /**
32
+ * Informational tooltip following the Adwaita / GNOME HIG pattern.
33
+ *
34
+ * Wraps a single trigger element and shows a floating label. Positioned
35
+ * automatically and flips if there is not enough space, mirroring
36
+ * `@gnome-ui/react`'s `Tooltip`.
37
+ *
38
+ * **Trigger differs from the web version by necessity**: the web `Tooltip`
39
+ * shows only on mouse hover / keyboard focus — touch has no hover state, so
40
+ * it explicitly never shows on touch. RN is touch-first, so the primary
41
+ * trigger here is long-press (`delayLongPress={delay}`, released via
42
+ * `onPressOut`) — the standard mobile "peek" idiom. `onHoverIn`/`onHoverOut`
43
+ * are also wired for hover-capable input (trackpad/mouse on iPad or a
44
+ * pointer-driven RN target) and `onFocus`/`onBlur` for external-keyboard
45
+ * accessibility, both delayed the same way the web version delays hover.
46
+ *
47
+ * Built on RN's own `Modal` (transparent, `pointerEvents="box-none"`), the
48
+ * same portal-substitute `Dialog` uses — no DOM `Portal` equivalent exists.
49
+ * Unlike `Dialog`, `visible` is set synchronously on trigger (not gated on
50
+ * the async `measureInWindow` result): the trigger's on-screen rect and the
51
+ * tooltip's own rendered size each resolve independently into state, and a
52
+ * separate effect computes the final position only once both have arrived.
53
+ * Gating `visible` itself on `measureInWindow`'s callback was tried first
54
+ * and dropped — that callback never fires in this package's Jest
55
+ * environment (no real native view to measure), which would make the
56
+ * component untestable, and in production it would also lose a real
57
+ * quick-tap-then-release press if the callback resolved after `onPressOut`
58
+ * had already fired.
59
+ *
60
+ * `role="tooltip"` ports 1:1 — RN's newer web-aligned `Role` union (the
61
+ * same one `Dialog` uses for `role="dialog"`) already has a `"tooltip"`
62
+ * value, no substitution needed. `aria-describedby` has no RN equivalent
63
+ * (no cross-platform description-relationship prop exists), so the label is
64
+ * set as the trigger's `accessibilityHint` instead — read after the
65
+ * trigger's own label by VoiceOver/TalkBack, the nearest analog. The CSS
66
+ * arrow reuses the same zero-size / transparent-border-on-three-sides
67
+ * triangle trick as the web version — RN Views support per-side
68
+ * `border*Color` just like CSS, the same technique `Spinner`'s ring
69
+ * already relies on, applied here to a triangle instead of an arc.
70
+ *
71
+ * Not ported: repositioning on scroll/resize while visible (the web
72
+ * version listens for both) — RN has no global scroll event, and a
73
+ * long-press is naturally cancelled by a scroll gesture starting, so the
74
+ * window to go stale is negligible for the touch trigger; orientation
75
+ * change mid-hover is an accepted edge case for a component this transient.
76
+ * `tooltipBgColor`/`tooltipFgColor` are not real `@gnome-ui/core` tokens
77
+ * (only referenced as CSS var fallbacks, never defined) — hardcoded to the
78
+ * same literal light/dark values as the web fallback, the same workaround
79
+ * `Spinner`'s track color already established for this class of gap.
80
+ *
81
+ * @example
82
+ * <Tooltip label="Save file">
83
+ * <Button accessibilityLabel="Save"><Icon icon={Save} /></Button>
84
+ * </Tooltip>
85
+ *
86
+ * @see https://developer.gnome.org/hig/patterns/feedback/tooltips.html
87
+ */
88
+ export declare const Tooltip: ({ label, placement: preferredPlacement, delay, children, }: TooltipProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { TooltipPlacement, TooltipProps } from './Tooltip';
2
+ export { Tooltip } from './Tooltip';