diff --git a/lib/components/DmIcon.tsx b/lib/components/DmIcon.tsx
index e0aeab1..cf3132c 100644
--- a/lib/components/DmIcon.tsx
+++ b/lib/components/DmIcon.tsx
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
import type { BoxProps } from './Box';
import { Image } from './Image';
-enum Direction {
+export enum Direction {
NORTH = 1,
SOUTH = 2,
EAST = 4,
diff --git a/lib/components/ImageButton.tsx b/lib/components/ImageButton.tsx
index 2ae069d..ad5d5dd 100644
--- a/lib/components/ImageButton.tsx
+++ b/lib/components/ImageButton.tsx
@@ -9,7 +9,7 @@ import type { ReactNode } from 'react';
import { type BooleanLike, classes } from '../common/react';
import { computeBoxProps } from '../common/ui';
import type { BoxProps } from './Box';
-import { DmIcon } from './DmIcon';
+import { type Direction, DmIcon } from './DmIcon';
import { Icon } from './Icon';
import { Image } from './Image';
import { Stack } from './Stack';
@@ -28,11 +28,11 @@ type Props = Partial<{
*/
buttons: ReactNode;
/**
- * Enables alternate layout for `buttons` container.
- * Without fluid, buttons will be on top and with `pointer-events: none`, useful for text info.
- * With fluid, buttons will be in "hamburger" style.
+ * Same as buttons, but. Have disabled pointer-events on content inside if non-fluid.
+ * Fluid version have humburger layout.
+ * Can be used with buttons prop.
*/
- buttonsAlt: boolean;
+ buttonsAlt: ReactNode;
/** Content under image. Or on the right if fluid. */
children: ReactNode;
/** Applies a CSS class to the element. */
@@ -51,6 +51,8 @@ type Props = Partial<{
dmIcon: string | null;
/** Parameter `icon_state` of component `DmIcon`. */
dmIconState: string | null;
+ /** Parameter `direction` of component `DmIcon`. */
+ dmDirection: Direction;
/**
* Changes the layout of the button, making it fill the entire horizontally available space.
* Allows the use of `title`
@@ -58,7 +60,7 @@ type Props = Partial<{
fluid: boolean;
/** Parameter responsible for the size of the image, component and standard "stubs". */
imageSize: number;
- /** Prop `src` of Image component. Example: `imageSrc={resolveAsset(thing.image}` */
+ /** Prop `src` of Image component. Example: `imageSrc={resolveAsset(thing.image)}` */
imageSrc: string;
/** Called when button is clicked with LMB. */
onClick: (e: any) => void;
@@ -75,6 +77,12 @@ type Props = Partial<{
}> &
BoxProps;
+/**
+ * Stylized button, with the ability to easily and simply insert any picture into it.
+ * - Without image, will be default question icon.
+ * - If an image is specified but for some reason cannot be displayed, there will be a spinner fallback until it is loaded.
+ * - Component has no **hover** effects, if `onClick` or `onRightClick` is not specified.
+ */
export function ImageButton(props: Props) {
const {
asset,
@@ -119,7 +127,8 @@ export function ImageButton(props: Props) {
{buttons}
)}
+ {buttonsAlt && (
+
+ {buttonsAlt}
+
+ )}
);
}
diff --git a/lib/styles/components/ImageButton.scss b/lib/styles/components/ImageButton.scss
index 8469213..8c33ca5 100644
--- a/lib/styles/components/ImageButton.scss
+++ b/lib/styles/components/ImageButton.scss
@@ -116,6 +116,7 @@ $bg-map: colors.$bg-map !default;
}
.ImageButton {
+ /* Better replace via inline-flex after Byond 516 will be stable */
display: inline-table;
position: relative;
text-align: center;
@@ -178,7 +179,7 @@ $bg-map: colors.$bg-map !default;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- padding: 0.25em 0.5em;
+ padding: 0.25em 0.33em;
margin: -1px;
border-radius: 0 0 0.33em 0.33em;
z-index: 2;
@@ -190,7 +191,7 @@ $bg-map: colors.$bg-map !default;
flex-direction: row;
position: relative;
text-align: center;
- margin: 0 0 0.5em 0;
+ margin: 0 0 0.33em 0;
user-select: none;
-ms-user-select: none;
diff --git a/stories/ImageButton.stories.tsx b/stories/ImageButton.stories.tsx
index 04032bf..f896902 100644
--- a/stories/ImageButton.stories.tsx
+++ b/stories/ImageButton.stories.tsx
@@ -1,9 +1,14 @@
import type { Meta, StoryObj } from '@storybook/react';
-import type { ComponentProps } from 'react';
-import { ImageButton } from '../lib/components/ImageButton';
+import { type ComponentProps, useState } from 'react';
+import { Button, Icon, ImageButton } from '../lib/components';
-type StoryProps = ComponentProps;
+const soulFish = (
+ SoulFish
+);
+const soulFishImage =
+ 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAIVBMVEXAwMAAAP8AAMwAZv9mMwCZZjMAAAD/mTP/zGb/ADMHBwd3bPqIAAAAAXRSTlMAQObYZgAAAI5JREFUKJFjYBhkQAiNz2iEJiAMEmBxQBIAaXENQOgwBgqwhEJVsKWlJRkbCsAF2NLKy9OSjQ0FVWEC5Rlt5cnGxsKmIVADKjo62oWBAoYwMyo6Z6AKlHd0lAMFlK1cYXrKywuNgQIL4AIMDEpAFauA9iIcthjkMgYXuACTlLKhAornFFctQvUtkyLDgAIAaJcdwdTNoTsAAAAASUVORK5CYII=';
+type StoryProps = ComponentProps;
export default {
component: ImageButton,
title: 'Components/ImageButton',
@@ -16,3 +21,196 @@ export const Default: Story = {
children: 'ImageButton',
},
};
+
+export const DefaultFluid: Story = {
+ args: {
+ fluid: true,
+ title: 'ImageButton',
+ children: 'It will take up the entire available width',
+ },
+};
+
+export const FilledDefault: Story = {
+ render: (args) => {
+ const [disabled, setDisabled] = useState(false);
+ const [selected, setSelected] = useState(false);
+
+ return (
+ setDisabled(!disabled)}
+ />
+ }
+ buttonsAlt={soulFish}
+ tooltip={'Also, you can Right Click on it'}
+ tooltipPosition={'bottom'}
+ onClick={() => setSelected(!selected)}
+ onRightClick={() => setDisabled(!disabled)}
+ >
+ Hover me
+
+ );
+ },
+};
+
+export const FilledFluid: Story = {
+ render: (args) => {
+ const [disabled, setDisabled] = useState(false);
+ const [selected, setSelected] = useState(false);
+
+ return (
+ setDisabled(!disabled)}
+ >
+
+
+ {disabled ? 'Enable' : 'Disable'}
+
+ }
+ tooltip={'Also, you can Right Click on it'}
+ tooltipPosition={'bottom'}
+ onClick={() => setSelected(!selected)}
+ onRightClick={() => setDisabled(!disabled)}
+ >
+ You can put any component you want inside "buttons" or "buttonsAlt"
+ props
+
+ );
+ },
+};
+
+export const Mixed: Story = {
+ render: (args) => {
+ const [disabled, setDisabled] = useState(false);
+ const [selected, setSelected] = useState(false);
+ const [compact, setCompact] = useState(false);
+
+ const info = (
+ <>
+ You can mix layouts without making new constants for each one.
+
+ If you are MAD enough.
+ >
+ );
+
+ const controls = (
+ <>
+