Added GroupActionButton component
• Added: - GroupActionButton component for handling group + relationships for joining, requesting, leaving groups • Updated: - Components where group actions exist
This commit is contained in:
parent
fb8c705ebf
commit
ed58ca4fe9
157
app/javascript/gabsocial/components/group_action_button.js
Normal file
157
app/javascript/gabsocial/components/group_action_button.js
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { injectIntl, defineMessages } from 'react-intl'
|
||||||
|
import {
|
||||||
|
joinGroup,
|
||||||
|
leaveGroup,
|
||||||
|
} from '../actions/groups'
|
||||||
|
import { openModal } from '../actions/modal'
|
||||||
|
import { me } from '../initial_state'
|
||||||
|
import {
|
||||||
|
CX,
|
||||||
|
MODAL_GROUP_PASSWORD,
|
||||||
|
} from '../constants'
|
||||||
|
import Button from './button'
|
||||||
|
import Text from './text'
|
||||||
|
|
||||||
|
class GroupActionButton extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
handleToggleMembership = () => {
|
||||||
|
const { group, relationships } = this.props
|
||||||
|
|
||||||
|
if (!group || !relationships) return false
|
||||||
|
|
||||||
|
const groupId = group.get('id')
|
||||||
|
const hasPassword = group.get('has_password')
|
||||||
|
const isMember = relationships.get('member')
|
||||||
|
const isRequested = relationships.get('requested')
|
||||||
|
|
||||||
|
if (isMember || isRequested) {
|
||||||
|
this.props.onLeaveGroup(groupId)
|
||||||
|
} else {
|
||||||
|
if (hasPassword) {
|
||||||
|
this.props.onOpenGroupPasswordModal(group)
|
||||||
|
} else {
|
||||||
|
this.props.onJoinGroup(groupId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
group,
|
||||||
|
intl,
|
||||||
|
relationships,
|
||||||
|
size,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
if (!group || !relationships) return null
|
||||||
|
|
||||||
|
let buttonText = ''
|
||||||
|
let buttonOptions = {}
|
||||||
|
|
||||||
|
const isPrivate = group.get('is_private')
|
||||||
|
const isMember = relationships.get('member')
|
||||||
|
const isRequested = relationships.get('requested')
|
||||||
|
|
||||||
|
if (isRequested) {
|
||||||
|
buttonText = intl.formatMessage(messages.requested)
|
||||||
|
buttonOptions = {
|
||||||
|
color: 'primary',
|
||||||
|
backgroundColor: 'tertiary',
|
||||||
|
}
|
||||||
|
} else if (isMember) {
|
||||||
|
buttonText = intl.formatMessage(messages.member)
|
||||||
|
buttonOptions = {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'brand',
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isPrivate && !isRequested) {
|
||||||
|
buttonText = intl.formatMessage(messages.request)
|
||||||
|
} else {
|
||||||
|
buttonText = intl.formatMessage(messages.join)
|
||||||
|
}
|
||||||
|
buttonOptions = {
|
||||||
|
color: 'brand',
|
||||||
|
backgroundColor: 'none',
|
||||||
|
isOutline: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSmall = size === 'small'
|
||||||
|
const textClassName = isSmall ? null : _s.px10
|
||||||
|
const textSize = isSmall ? 'small' : 'medium'
|
||||||
|
const textWeight = isSmall ? 'normal' : 'bold'
|
||||||
|
|
||||||
|
const btnClasses = CX({
|
||||||
|
px10: isSmall,
|
||||||
|
minW76PX: isSmall,
|
||||||
|
jcCenter: 1,
|
||||||
|
aiCenter: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
{...buttonOptions}
|
||||||
|
onClick={this.handleToggleMembership}
|
||||||
|
className={btnClasses}
|
||||||
|
isNarrow={isSmall}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
color='inherit'
|
||||||
|
align='center'
|
||||||
|
weight={textWeight}
|
||||||
|
size={textSize}
|
||||||
|
className={textClassName}
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
||||||
|
request: { id: 'groups.request_join', defaultMessage: 'Request to Join' },
|
||||||
|
requested: { id: 'groups.requested', defaultMessage: 'Requested' },
|
||||||
|
member: { id: 'groups.member', defaultMessage: 'Member' },
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onJoinGroup(groupId) {
|
||||||
|
dispatch(joinGroup(groupId))
|
||||||
|
},
|
||||||
|
onLeaveGroup(groupId) {
|
||||||
|
dispatch(leaveGroup(groupId))
|
||||||
|
},
|
||||||
|
onOpenGroupPasswordModal(group) {
|
||||||
|
dispatch(openModal(MODAL_GROUP_PASSWORD, {
|
||||||
|
group,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
GroupActionButton.propTypes = {
|
||||||
|
group: ImmutablePropTypes.map,
|
||||||
|
relationships: ImmutablePropTypes.map,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
size: PropTypes.oneOf([
|
||||||
|
'small',
|
||||||
|
'normal',
|
||||||
|
]),
|
||||||
|
onJoin: PropTypes.func.isRequired,
|
||||||
|
onLeave: PropTypes.func.isRequired,
|
||||||
|
onOpenGroupPasswordModal: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupActionButton.defaultProps = {
|
||||||
|
size: 'normal',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default injectIntl(connect(null, mapDispatchToProps)(GroupActionButton))
|
@ -4,9 +4,7 @@ import { connect } from 'react-redux'
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import { openPopover, closePopover } from '../actions/popover'
|
import { openPopover } from '../actions/popover'
|
||||||
import { openModal } from '../actions/modal'
|
|
||||||
import { joinGroup, leaveGroup } from '../actions/groups'
|
|
||||||
import {
|
import {
|
||||||
addShortcut,
|
addShortcut,
|
||||||
removeShortcut,
|
removeShortcut,
|
||||||
@ -17,6 +15,7 @@ import {
|
|||||||
} from '../constants'
|
} from '../constants'
|
||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
import Responsive from '../features/ui/util/responsive_component'
|
import Responsive from '../features/ui/util/responsive_component'
|
||||||
|
import GroupActionButton from './group_action_button'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Block from './block'
|
import Block from './block'
|
||||||
import Heading from './heading'
|
import Heading from './heading'
|
||||||
@ -28,11 +27,6 @@ import Text from './text'
|
|||||||
|
|
||||||
class GroupHeader extends ImmutablePureComponent {
|
class GroupHeader extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleOnToggleMembership = () => {
|
|
||||||
const { group, relationships } = this.props
|
|
||||||
this.props.onToggleMembership(group, relationships);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnOpenGroupOptions = () => {
|
handleOnOpenGroupOptions = () => {
|
||||||
const { relationships } = this.props
|
const { relationships } = this.props
|
||||||
const isAdmin = !!relationships ? relationships.get('admin') : false
|
const isAdmin = !!relationships ? relationships.get('admin') : false
|
||||||
@ -75,31 +69,13 @@ class GroupHeader extends ImmutablePureComponent {
|
|||||||
const title = !!group ? group.get('title') : undefined
|
const title = !!group ? group.get('title') : undefined
|
||||||
const slug = !!group ? !!group.get('slug') ? `g/${group.get('slug')}` : undefined : undefined
|
const slug = !!group ? !!group.get('slug') ? `g/${group.get('slug')}` : undefined : undefined
|
||||||
const isPrivate = !!group ? group.get('is_private') : false
|
const isPrivate = !!group ? group.get('is_private') : false
|
||||||
|
const isAdminOrMod = !!relationships ? (relationships.get('admin') || relationships.get('moderator')) : false
|
||||||
let isAdminOrMod = false
|
|
||||||
let actionButtonTitle
|
|
||||||
let actionButtonOptions = {}
|
|
||||||
if (relationships) {
|
|
||||||
isAdminOrMod = relationships.get('admin') || relationships.get('moderator')
|
|
||||||
const isMember = relationships.get('member')
|
|
||||||
|
|
||||||
actionButtonTitle = intl.formatMessage(isMember ? messages.member : messages.join)
|
|
||||||
actionButtonOptions = {
|
|
||||||
isOutline: !isMember,
|
|
||||||
backgroundColor: isMember ? 'brand' : 'none',
|
|
||||||
color: isMember ? 'white' : 'brand',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tabs = !group ? [] : [
|
const tabs = !group ? [] : [
|
||||||
{
|
{
|
||||||
to: `/groups/${group.get('id')}`,
|
to: `/groups/${group.get('id')}`,
|
||||||
title: 'Timeline',
|
title: 'Timeline',
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// to: `/groups/${group.get('id')}/media`,
|
|
||||||
// title: 'Media',
|
|
||||||
// },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if (isAdminOrMod && group) {
|
if (isAdminOrMod && group) {
|
||||||
@ -146,23 +122,15 @@ class GroupHeader extends ImmutablePureComponent {
|
|||||||
{
|
{
|
||||||
!!me &&
|
!!me &&
|
||||||
<div className={[_s.d, _s.flexRow, _s.jcCenter, _s.aiCenter, _s.mt5, _s.pb15, _s.pt5, _s.h100PC, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.jcCenter, _s.aiCenter, _s.mt5, _s.pb15, _s.pt5, _s.h100PC, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15].join(' ')}>
|
||||||
{
|
<GroupActionButton
|
||||||
!!actionButtonTitle &&
|
group={group}
|
||||||
<Button
|
relationships={relationships}
|
||||||
className={_s.mr5}
|
/>
|
||||||
onClick={this.handleOnToggleMembership}
|
|
||||||
{...actionButtonOptions}
|
|
||||||
>
|
|
||||||
<Text color='inherit' size='medium' weight='bold' className={_s.px10}>
|
|
||||||
{actionButtonTitle}
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
color='primary'
|
color='primary'
|
||||||
backgroundColor='tertiary'
|
backgroundColor='tertiary'
|
||||||
className={[_s.px10, _s.mr5].join(' ')}
|
className={[_s.px10, _s.mr5, _s.ml5].join(' ')}
|
||||||
icon='ellipsis'
|
icon='ellipsis'
|
||||||
onClick={this.handleOnOpenGroupOptions}
|
onClick={this.handleOnOpenGroupOptions}
|
||||||
buttonRef={this.setInfoBtn}
|
buttonRef={this.setInfoBtn}
|
||||||
@ -236,18 +204,12 @@ class GroupHeader extends ImmutablePureComponent {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{
|
|
||||||
!!actionButtonTitle &&
|
<GroupActionButton
|
||||||
<Button
|
group={group}
|
||||||
className={_s.mr5}
|
relationships={relationships}
|
||||||
onClick={this.handleOnToggleMembership}
|
/>
|
||||||
{...actionButtonOptions}
|
|
||||||
>
|
|
||||||
<Text color='inherit' size='medium' weight='bold' className={_s.px10}>
|
|
||||||
{actionButtonTitle}
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -262,8 +224,6 @@ class GroupHeader extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
|
||||||
member: { id: 'groups.member', defaultMessage: 'Member' },
|
|
||||||
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
||||||
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
||||||
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' }
|
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' }
|
||||||
@ -280,13 +240,6 @@ const mapStateToProps = (state, { group }) => {
|
|||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
|
|
||||||
onToggleMembership(group, relationships) {
|
|
||||||
if (relationships.get('member')) {
|
|
||||||
dispatch(leaveGroup(group.get('id')))
|
|
||||||
} else {
|
|
||||||
dispatch(joinGroup(group.get('id')))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onOpenGroupOptions(targetRef, group, options) {
|
onOpenGroupOptions(targetRef, group, options) {
|
||||||
dispatch(openPopover('GROUP_OPTIONS', {
|
dispatch(openPopover('GROUP_OPTIONS', {
|
||||||
targetRef,
|
targetRef,
|
||||||
@ -311,7 +264,6 @@ GroupHeader.propTypes = {
|
|||||||
isShortcut: PropTypes.bool.isRequired,
|
isShortcut: PropTypes.bool.isRequired,
|
||||||
isXS: PropTypes.bool,
|
isXS: PropTypes.bool,
|
||||||
onAddShortcut: PropTypes.func.isRequired,
|
onAddShortcut: PropTypes.func.isRequired,
|
||||||
onToggleMembership: PropTypes.func.isRequired,
|
|
||||||
onRemoveShortcut: PropTypes.func.isRequired,
|
onRemoveShortcut: PropTypes.func.isRequired,
|
||||||
onOpenGroupOptions: PropTypes.func.isRequired,
|
onOpenGroupOptions: PropTypes.func.isRequired,
|
||||||
relationships: ImmutablePropTypes.map,
|
relationships: ImmutablePropTypes.map,
|
||||||
|
@ -5,7 +5,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
|||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import { joinGroup, leaveGroup } from '../actions/groups'
|
|
||||||
import { CX } from '../constants'
|
import { CX } from '../constants'
|
||||||
import { PLACEHOLDER_MISSING_HEADER_SRC } from '../constants'
|
import { PLACEHOLDER_MISSING_HEADER_SRC } from '../constants'
|
||||||
import { shortNumberFormat } from '../utils/numbers'
|
import { shortNumberFormat } from '../utils/numbers'
|
||||||
@ -13,26 +12,10 @@ import Button from './button'
|
|||||||
import Image from './image'
|
import Image from './image'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import Dummy from './dummy'
|
import Dummy from './dummy'
|
||||||
|
import GroupActionButton from './group_action_button'
|
||||||
|
|
||||||
class GroupListItem extends ImmutablePureComponent {
|
class GroupListItem extends ImmutablePureComponent {
|
||||||
|
|
||||||
state = {
|
|
||||||
hovering: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnToggleMembership = () => {
|
|
||||||
const { group, relationships } = this.props
|
|
||||||
this.props.onToggleMembership(group.get('id'), relationships)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnMouseEnter = () => {
|
|
||||||
this.setState({ hovering: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnMouseLeave = () => {
|
|
||||||
this.setState({ hovering: false })
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
group,
|
group,
|
||||||
@ -43,7 +26,6 @@ class GroupListItem extends ImmutablePureComponent {
|
|||||||
isStatic,
|
isStatic,
|
||||||
relationships,
|
relationships,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { hovering } = this.state
|
|
||||||
|
|
||||||
if (!group) return null
|
if (!group) return null
|
||||||
|
|
||||||
@ -63,6 +45,7 @@ class GroupListItem extends ImmutablePureComponent {
|
|||||||
borderBottom1PX: !isLast,
|
borderBottom1PX: !isLast,
|
||||||
flexRow: 1,
|
flexRow: 1,
|
||||||
py5: 1,
|
py5: 1,
|
||||||
|
px5: isAddable,
|
||||||
w100PC: 1,
|
w100PC: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -71,14 +54,12 @@ class GroupListItem extends ImmutablePureComponent {
|
|||||||
flexRow: 1,
|
flexRow: 1,
|
||||||
noUnderline: 1,
|
noUnderline: 1,
|
||||||
w100PC: 1,
|
w100PC: 1,
|
||||||
maxW100PC86PX: isAddable,
|
flexGrow1: isAddable,
|
||||||
|
flexShrink1: isAddable,
|
||||||
})
|
})
|
||||||
|
|
||||||
const coverSrc = group.get('cover_image_url') || ''
|
const coverSrc = group.get('cover_image_url') || ''
|
||||||
const coverMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc
|
const coverMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc
|
||||||
const isMember = !!relationships && relationships.get('member')
|
|
||||||
const addButtonColor = isMember ? hovering ? 'danger' : 'tertiary' : 'brand'
|
|
||||||
const addButtonTitle = isMember ? hovering ? 'Leave' : 'Member' : 'Join'
|
|
||||||
|
|
||||||
const Wrapper = !isStatic ? NavLink : Dummy
|
const Wrapper = !isStatic ? NavLink : Dummy
|
||||||
|
|
||||||
@ -114,20 +95,11 @@ class GroupListItem extends ImmutablePureComponent {
|
|||||||
{
|
{
|
||||||
isAddable &&
|
isAddable &&
|
||||||
<div className={[_s.d, _s.jcCenter, _s.flexGrow1].join(' ')}>
|
<div className={[_s.d, _s.jcCenter, _s.flexGrow1].join(' ')}>
|
||||||
{
|
<GroupActionButton
|
||||||
relationships &&
|
group={group}
|
||||||
<Button
|
relationships={relationships}
|
||||||
isNarrow
|
size='small'
|
||||||
color='white'
|
/>
|
||||||
className={[_s.px10, _s.w76PX].join(' ')}
|
|
||||||
backgroundColor={addButtonColor}
|
|
||||||
onClick={this.handleOnToggleMembership}
|
|
||||||
onMouseEnter={this.handleOnMouseEnter}
|
|
||||||
onMouseLeave={this.handleOnMouseLeave}
|
|
||||||
>
|
|
||||||
<Text size='small' color='inherit' align='center'>{addButtonTitle}</Text>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -145,23 +117,12 @@ const mapStateToProps = (state, { id }) => ({
|
|||||||
relationships: state.getIn(['group_relationships', id]),
|
relationships: state.getIn(['group_relationships', id]),
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
onToggleMembership(groupId, relationships) {
|
|
||||||
if (relationships.get('member')) {
|
|
||||||
dispatch(leaveGroup(groupId))
|
|
||||||
} else {
|
|
||||||
dispatch(joinGroup(groupId))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
GroupListItem.propTypes = {
|
GroupListItem.propTypes = {
|
||||||
group: ImmutablePropTypes.map,
|
group: ImmutablePropTypes.map,
|
||||||
isAddable: PropTypes.bool,
|
isAddable: PropTypes.bool,
|
||||||
isHidden: PropTypes.bool,
|
isHidden: PropTypes.bool,
|
||||||
isLast: PropTypes.bool,
|
isLast: PropTypes.bool,
|
||||||
isStatic: PropTypes.bool,
|
isStatic: PropTypes.bool,
|
||||||
onToggleMembership: PropTypes.func.isRequired,
|
|
||||||
relationships: ImmutablePropTypes.map,
|
relationships: ImmutablePropTypes.map,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,4 +130,4 @@ GroupListItem.defaultProps = {
|
|||||||
isLast: false,
|
isLast: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GroupListItem))
|
export default injectIntl(connect(mapStateToProps)(GroupListItem))
|
@ -516,6 +516,7 @@ pre {
|
|||||||
.maxW100PC42PX { max-width: calc(100% - 42px); }
|
.maxW100PC42PX { max-width: calc(100% - 42px); }
|
||||||
|
|
||||||
.minW330PX { min-width: 330px; }
|
.minW330PX { min-width: 330px; }
|
||||||
|
.minW76PX { min-width: 76px; }
|
||||||
.minW20PX { min-width: 20px; }
|
.minW20PX { min-width: 20px; }
|
||||||
.minW14PX { min-width: 14px; }
|
.minW14PX { min-width: 14px; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user